perm filename HAL.CRF[HAL,HE] blob sn#256759 filedate 1977-01-10 generic text, type T, neo UTF8
≠COMMEN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 1
	HAL PAL[HAL,HE]	PAGE 1 	

≥				COMMENT ⊗   VALID 00003 PAGES
≥				C REC  PAGE   DESCRIPTION
≥				C00001 00001
≥				C00002 00002	.TITLE  AL INTERPRETER
≥				C00006 00003	 program initialization
≥				C00016 ENDMK
≥					C⊗;
≠.TITLE≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 2
	HAL PAL[HAL,HE]	PAGE 2 	

≥					.TITLE  AL INTERPRETER
≥					
≥					;These need only be looked at during the first pass:
≠.IF1≡≥					    .IF1
≥					        .INSRT HALHED.PAL[HAL,HE]
≥					
≥						STSW  FLOAT,1	;1 => put in the floating-string conversions
≥						STSW  KERNEL,1	;1 => use the kernel
≥						STSW  SMALLB,1	;1 => use the small block routines
≥						STSW  ONMONS,1	;1 => put in condition monitors
≥						STSW  GRAPHS,1	;1 => put in graph structure
≥						STSW  MOVING,1	;1 => assume the servo is loaded too
≥						STSW  INTLOAD,1	;1 => put in the interpreter
≥						STSW  ALAID,1	;1 => put in the ALAID debugging stuff
≥						STSW  DETECT,0	;1 => put in the collision detector only
≥						STSW  MAP,0	;1 => put in mapping capablity.  Obsolete.
≥						STSW  LBDEBUG,0	;1 => first word of any large block is address of maker.
≥						STSW  YELLOW,0	;1 => the yellow arm is in.
≥					
≥					        .INSRT K1DEF.PAL[11,SYS]
≥					    .ENDC
≥					
≡INTRP≡≥		014100			. = INTRP
≥					
≠.INSRT≡≥					.INSRT HALIO.PAL[HAL,HE]
≠COMMEN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 3
	HALIO PAL[HAL,HE]	PAGE 1 	

≥				COMMENT ⊗   VALID 00005 PAGES
≥				C REC  PAGE   DESCRIPTION
≥				C00001 00001
≥				C00002 00002	.SBTTL	Basic TTY input and output routines
≥				C00003 00003	 TTY output routines  TYPSTR, TYPDEC, TYPOCT, TYPCHR
≥				C00008 00004	 Macros:  OUTSTR, NUMOUT, ASCIE, CRLF, HALERR, ERRTRAP
≥				C00012 00005	 IOINIT, INSTR, system line buffers
≥				C00015 ENDMK
≥					C⊗;
≠.SBTTL≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 4
	HALIO PAL[HAL,HE]	PAGE 2 	Basic TTY input and output routines

≥					.SBTTL	Basic TTY input and output routines
≠.EVEN≡≥		014100			.EVEN
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 5
	HALIO PAL[HAL,HE]	PAGE 3 	Basic TTY input and output routines

≥					; TTY output routines  TYPSTR, TYPDEC, TYPOCT, TYPCHR
≥					
≥					;  Modified 5-Sep-74 by RF.  Originally written by KKP.
≥					
≠COMMEN≡≥				COMMENT ⊗ Output a string, ending with a zero character. Pointer to
≥					start of string in R0.  Called in "simple" style. ⊗
≥					
≠MOV≡≡R0≡≡R1≡≥	014100	010001			TYPSTR:	MOV R0,R1	;R1 ← LOC[STRING]
≠MOVB≡≡R1≡≡R0≡≥	014102	112100				MOVB (R1)+,R0	;R0 ← first byte of string
≠BEQ≡≥	014104	001404			1$:	BEQ 2$		;If null, exit now.
≠JSR≡≡PC≡≡TYPCHR≡≥	014106	004767	000056			JSR PC,TYPCHR	;Type this one character
≠MOVB≡≡R1≡≡R0≡≥	014112	112100				MOVB (R1)+,R0	;R0 ← Next byte of string
≠BNE≡≥	014114	001373				BNE 1$		;If more to come, repeat.
≠RTS≡≡PC≡≥	014116	000207			2$:	RTS PC		;Done
≥					
≥					
≠COMMEN≡≥				COMMENT ⊗ Routines to output numbers.  Argument in R0.  TYPDEC
≥				outputs in base 10, and TYPOCT in base 8.  Both use TYPDIG as a
≥				subroutine, putting the digit in R0.  TYPCHR is a general purpose
≥				character output routine.  It looks at OUTSW to see where to direct
≥					the output. ⊗
≥					
≠MOV≡≡RADIX≡≥	014120	012767	000012	000020	TYPDEC:	MOV #12,RADIX	;To output in base 10
≠BR≡≡TYPDIG≡≥	014126	000404				BR TYPDIG	;Go type it.
≠MOV≡≡RADIX≡≥	014130	012767	000010	000010	TYPOCT:	MOV #8,RADIX	;To output in base 8.
≠BR≡≡TYPDIG≡≥	014136	000400				BR TYPDIG	;Go type it.
≠MOV≡≡R0≡≡R1≡≥	014140	010001			TYPDIG:	MOV R0,R1	;Need dividend in R1, with R0 clear.
≠CLR≡≡R0≡≥	014142	005000				CLR R0		;Clear upper half of dividend.
≠DIV≡≡PC≡≡R0≡≥	014144	071027				DIV (PC)+,R0	;Divide argument in R0, R1 by radix.
≥	014146	000012			RADIX:	12		;Starts out in decimal.
≠BEQ≡≡TYPOUT≡≥	014150	001404				BEQ TYPOUT	;If quotient zero, then can print.
≠MOV≡≡R1≡≡SP≡≥	014152	010146				MOV R1,-(SP)	;Else stack quotient
≠JSR≡≡PC≡≡TYPDIG≡≥	014154	004767	777760		 	JSR PC,TYPDIG	;Recursive call.
≠MOV≡≡SP≡≡R1≡≥	014160	012601				MOV (SP)+,R1	;Unstack last quotient
≠ADD≡≡R1≡≥	014162	062701	000060		TYPOUT:	ADD #'0,R1	;Form TTY code for digit
≠MOV≡≡R1≡≡R0≡≥	014166	010100				MOV R1,R0	;Need argument for TYPCHR in R0.
≠TST≡≡OUTSW≡≥	014170	005767	143576		TYPCHR:	TST OUTSW	;VT05 or console?
≠BEQ≡≥	014174	001423				BEQ 3$		;
≠TSTB≡≡KBOS≡≥	014176	105767	163362			TSTB KBOS	;VT05: Is it available?
≠BMI≡≥	014202	100404				BMI 2$		;Yes.
≥					1$:
≠.IFDF≡≡KERNEL≡≥					    .IFDF KERNEL
≠.IFNZ≡≡KERNEL≡≥		000001			    .IFNZ KERNEL
≤SLEEP≡≥						SLEEP #2	;No.  Sleep a while, try again
≤.ARG≡≥						  .ARG #2
≠.LIF≡≥						    .LIF NB #2
≠MOV≡≡SP≡≥	014204	012746	000002			      MOV #2,-(SP)
≥	014210	104014				104014
≥					    .ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 6
	HALIO PAL[HAL,HE]	PAGE 3.1 	Basic TTY input and output routines

≥					    .ENDC
≠BR≡≡TYPCHR≡≥	014212	000766				BR TYPCHR	;
≠MOVB≡≡R0≡≡KBOR≡≥	014214	110067	163346		2$:	MOVB R0,KBOR	;Output a byte to it.
≠CMP≡≡R0≡≥	014220	022700	000012			CMP #12,R0	;Was it a line feed?
≠BNE≡≡TYPRET≡≥	014224	001017				BNE TYPRET	;If not that code, then done.
≠CLR≡≡R0≡≥	014226	005000				CLR R0		;Otherwise, output 3 nulls.
≠JSR≡≡PC≡≡TYPCHR≡≥	014230	004767	777734			JSR PC,TYPCHR	;
≠JSR≡≡PC≡≡TYPCHR≡≥	014234	004767	777730			JSR PC,TYPCHR	;
≠JMP≡≡TYPCHR≡≥	014240	000167	777724			JMP TYPCHR	;Direct jump; it will return to caller.
≠TSTB≡≡OREG≡≥	014244	105767	143526		3$:	TSTB OREG	;Console:  Ready?
≠BNE≡≥	014250	001355				BNE 1$		;No.
≠MOVB≡≡R0≡≡OREG≡≥	014252	110067	143520			MOVB R0,OREG	;Yes.  Output a byte to it.
≠MOV≡≥	014256	012767	000001	156302		MOV #1,172566	;Wake up pdp10 by generating interrupt
≠RTS≡≡PC≡≥	014264	000207			TYPRET:	RTS PC		;Return.
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 7
	HALIO PAL[HAL,HE]	PAGE 4 	Basic TTY input and output routines

≥					; Macros:  OUTSTR, NUMOUT, ASCIE, CRLF, HALERR, ERRTRAP
≥					
≠.MACRO≡≤OUTSTR≠≥					       .MACRO OUTSTR B	;Type string starting at B.
≥						MOV R0,-(SP)	;Save R0.  Who knows what was happening in it?
≥						MOV R1,-(SP)	;Save R1.
≥						MOV #B,R0	;Load up the string to be output
≥						JSR PC,TYPSTR	;Call the string output utility routine.
≥						MOV (SP)+,R1	;Restore R1.
≥						MOV (SP)+,R0	;Restore R0.
≥					       .ENDM
≥					
≠.MACRO≡≤NUMOUT≠≥					       .MACRO NUMOUT	;Type out the number in AC0 with CVG using OUTBUF
≥						MOV R0,-(SP)	;Save the registers
≥						MOV R1,-(SP)
≥						STF AC0,-(SP)
≥						STF AC1,-(SP)
≥						MOV #OUTBUF,R0	;Use OUTBUF to construct the string
≥						JSR PC,CVG	;Convert floating point number to asc
≥						LDF (SP)+,AC1   ;Restore the floating point registers
≥						LDF (SP)+,AC0
≥						MOV #OUTBUF,R0	;Set pointer for i/o routine
≥						JSR PC,TYPSTR	;Type out the number
≥						MOV (SP)+,R1	;Restore the registers
≥						MOV (SP)+,R0
≥					       .ENDM
≥					
≠.MACRO≡≤ASCIE≠≥					       .MACRO ASCIE STR
≥					       .ASCIZ STR
≥					       .EVEN
≥					       .ENDM
≥					
≠.MACRO≡≤CRLF≠≥					       .MACRO	CRLF
≥						OUTSTR CRLFX	;Carriage return, line feed.
≥					       .ENDM
≥					
≠.ASCIZ≡≥	014266	   015		
≥	014267	   012			CRLFX: .ASCIZ /
≥	014270	   000		
≥					/
≥					
≤ASCIE≡≥				RUGMES:	ASCIE </π
≥				--ONLY DDT CAN HELP YOU NOW!
≥					π/>
≠.ASCIZ≡≥	014271	   007		
≥	014272	   015		
≥	014273	   012			       .ASCIZ /π
≥	014274	   055		
≥	014275	   055		
≥	014276	   117		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 8
	HALIO PAL[HAL,HE]	PAGE 4.1 	Basic TTY input and output routines

≥	014277	   116		
≥	014300	   114		
≥	014301	   131		
≥	014302	   040		
≥	014303	   104		
≥	014304	   104		
≥	014305	   124		
≥	014306	   040		
≥	014307	   103		
≥	014310	   101		
≥	014311	   116		
≥	014312	   040		
≥	014313	   110		
≥	014314	   105		
≥	014315	   114		
≥	014316	   120		
≥	014317	   040		
≥	014320	   131		
≥	014321	   117		
≥	014322	   125		
≥	014323	   040		
≥	014324	   116		
≥	014325	   117		
≥	014326	   127		
≥	014327	   041		
≥	014330	   015		
≥	014331	   012			--ONLY DDT CAN HELP YOU NOW!
≥	014332	   007		
≥	014333	   000		
≥					π/
≠.EVEN≡≥		014334			       .EVEN
≥					
≥					ERRTRAP:
≥					; Pointer to message is on stack.  Print it, restore state, go to DDT
≠MOV≡≡R0≡≡SP≡≥	014334	010046				MOV R0,-(SP)	;Save R0.
≠MOV≡≡R1≡≡SP≡≥	014336	010146				MOV R1,-(SP)	;Save R1.
≠.IFDF≡≡KERNEL≡≥					    .IFDF KERNEL
≠.IFNZ≡≡KERNEL≡≥		000001			    .IFNZ KERNEL
≤EVWAIT≡≥						EVWAIT CSLEVT	;Grab the console
≤.ARG≡≥						  .ARG CSLEVT
≠.LIF≡≥						    .LIF NB CSLEVT
≠MOV≡≡CSLEVT≡≡SP≡≥	014340	016746	000052			      MOV CSLEVT,-(SP)
≥	014344	104010				104010
≥					    .ENDC
≥					    .ENDC
≠MOV≡≡CRLFX≡≡R0≡≥	014346	012700	014266			MOV #CRLFX,R0	;Move to new line
≠JSR≡≡PC≡≡TYPSTR≡≥	014352	004767	777522			JSR PC,TYPSTR	;
≠MOV≡≡SP≡≡R0≡≥	014356	016600	000006			MOV 6(SP),R0	;Type out message
≠JSR≡≡PC≡≡TYPSTR≡≥	014362	004767	777512			JSR PC,TYPSTR	;
≠MOV≡≡RUGMES≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 9
	HALIO PAL[HAL,HE]	PAGE 4.2 	Basic TTY input and output routines

≥	014366	012700	014271			MOV #RUGMES,R0	;Type out RUGMES
≠JSR≡≡PC≡≡TYPSTR≡≥	014372	004767	777502			JSR PC,TYPSTR	;
≠.IFDF≡≡KERNEL≡≥					    .IFDF KERNEL
≠.IFNZ≡≡KERNEL≡≥		000001			    .IFNZ KERNEL
≤EVSIG≡≥						EVSIG CSLEVT	;Release the console
≤.ARG≡≥						  .ARG CSLEVT
≠.LIF≡≥						    .LIF NB CSLEVT
≠MOV≡≡CSLEVT≡≡SP≡≥	014376	016746	000014			      MOV CSLEVT,-(SP)
≥	014402	104012				104012
≥					    .ENDC
≥					    .ENDC
≠MOV≡≡SP≡≡R1≡≥	014404	012601				MOV (SP)+,R1	;Restore R1.
≠MOV≡≡SP≡≡R0≡≥	014406	012600				MOV (SP)+,R0	;Restore R0.
≠MOV≡≡SP≡≡SP≡≥	014410	012616				MOV (SP)+,(SP)	;put return address only on stack.
≠BPT≡≠BPT≡≥	014412	000003				BPT		;Breakpoint to DDT.
≠RTS≡≡PC≡≥	014414	000207				RTS PC		;Return to calling point.
≥					
≤PUTLOC≡≥					PUTLOC LERRTRAP, ERRTRAP
≡II≠≥		014416			        II==.
≡LERRTR≡≥		014012			        .= LERRTRAP
≡ERRTRA≡≡ERRTRA≡≥	014012	014334			         ERRTRAP
≡II≡≥		014416			       .=II
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 10
	HALIO PAL[HAL,HE]	PAGE 5 	Basic TTY input and output routines

≥					; IOINIT, INSTR, system line buffers
≥					
≥	014416	000000			CSLEVT:	0		;Console interlock event
≥					IOINIT:
≠.IFDF≡≡KERNEL≡≥					    .IFDF KERNEL
≠.IFNZ≡≡KERNEL≡≥		000001			    .IFNZ KERNEL
≤EVMAK≡≥						EVMAK		;
≥	014420	104004				104004
≠MOV≡≡SP≡≡CSLEVT≡≥	014422	011667	777770			MOV (SP),CSLEVT	;
≤EVSIG≡≥						EVSIG		;Make a console interlock event
≤.ARG≡≥						  .ARG 
≠.LIF≡≥						    .LIF NB 
≥						      MOV ,-(SP)
≥	014426	104012				104012
≥					    .ENDC
≥					    .ENDC
≠RTS≡≡PC≡≥	014430	000207				RTS PC		;
≥					
≠COMMEN≡≥				COMMENT ⊗ String byte pointer argument in R0.  A carriage return is
≥				assumed to be the activation character. A rubout is a deleting
≥				backspace character.  At the completion of this routine a null
≥				character is placed at the end of the input string.  R0 then points
≥				to the null character.  Registers used: R0 passes the argument, R1 is
≥					garbaged.  ⊗
≥					
≠CLR≡≡CCNT≡≥	014432	005067	000172		INSTR:	CLR	CCNT		;RESET CHARACTER COUNT
≠TST≡≡OUTSW≡≥	014436	005767	143330		IN2:	TST 	OUTSW		;VT05 OR CONSOLE?
≠BEQ≡≡CONSIN≡≥	014442	001406				BEQ 	CONSIN	
≠TSTB≡≡KBIS≡≥	014444	105767	163110			TSTB	KBIS		;TEST IF KEYBOARD READY
≠BEQ≡≡IN2≡≥	014450	001772				BEQ	IN2		;WAIT TILL IT IS
≠MOVB≡≡KBIR≡≡R1≡≥	014452	116701	163104			MOVB	KBIR,R1		;GET A CHARACTER
≠BR≡≡GOTCAR≡≥	014456	000405				BR	GOTCAR
≠MOV≡≡IREG≡≡R1≡≥	014460	016701	143310		CONSIN:	MOV	IREG,R1		;BYTE FROM PDP10?
≠BEQ≡≡IN2≡≥	014464	001764				BEQ	IN2		;NO
≠CLR≡≡IREG≡≥	014466	005067	143302			CLR	IREG
≠BIC≡≡R1≡≥	014472	042701	177600		GOTCAR:	BIC     #177600,R1	;MASK OFF - MAKE IT 7 BITS
≠CMP≡≡R1≡≥	014476	020127	000177			CMP	R1,#177		;COMPARE TO BS CHARACTER
≠BNE≡≥	014502	001017				BNE	1$		;SKIP IF ITS NOT
≠TST≡≡CCNT≡≥	014504	005767	000120			TST	CCNT		;CHECK IF ANY CHARACTERS IN BUFFER
≠BEQ≡≡IN2≡≥	014510	001752				BEQ	IN2		;FORGET BACK SPACE IF NO CHAR.
≠DEC≡≡R0≡≥	014512	005300				DEC     R0   		;REMOVE LAST CHARACTER IN BUFFER
≠DEC≡≡CCNT≡≥	014514	005367	000110			DEC	CCNT		;DECREMENT CHARACTER COUNT
≤OUTSTR≡≥						OUTSTR  DBS		;PERFORM A DELETING BACKSPACE
≠MOV≡≡R0≡≡SP≡≥	014520	010046				MOV R0,-(SP)	;Save R0.  Who knows what was happening in it?
≠MOV≡≡R1≡≡SP≡≥	014522	010146				MOV R1,-(SP)	;Save R1.
≠MOV≡≡DBS≡≡R0≡≥	014524	012700	014632			MOV #DBS,R0	;Load up the string to be output
≠JSR≡≡PC≡≡TYPSTR≡≥	014530	004767	777344			JSR PC,TYPSTR	;Call the string output utility routine.
≠MOV≡≡SP≡≡R1≡≥	014534	012601				MOV (SP)+,R1	;Restore R1.
≠MOV≡≡SP≡≡R0≡≥	014536	012600				MOV (SP)+,R0	;Restore R0.
≠BR≡≡IN2≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 11
	HALIO PAL[HAL,HE]	PAGE 5.1 	Basic TTY input and output routines

≥	014540	000736				BR      IN2
≠CMP≡≡R1≡≥	014542	020127	000015		1$:	CMP	R1,#15		;COMPARE TO CR CHARACTER
≠BEQ≡≥	014546	001414				BEQ     2$   		;CONTINUE READING IF ITS NOT A CR
≠CMP≡≡R1≡≥	014550	020127	000040			CMP	R1,#40		;CHECK IF CHARACTER LEGAL
≠BLT≡≡IN2≡≥	014554	002730				BLT	IN2		;IGNOR IF IT IS
≠MOVB≡≡R1≡≡R0≡≥	014556	110120			    	MOVB	R1,(R0)+	;SAVE THE CHARACTER
≠INC≡≡CCNT≡≥	014560	005267	000044		    	INC	CCNT		;INCREMENT CHARACTER COUNT
≠MOV≡≡R0≡≡SP≡≥	014564	010046				MOV	R0,-(SP)	;ECHO THE CHARACTER
≠MOV≡≡R1≡≡R0≡≥	014566	010100				MOV	R1,R0
≠JSR≡≡PC≡≡TYPCHR≡≥	014570	004767	777374			JSR	PC,TYPCHR
≠MOV≡≡SP≡≡R0≡≥	014574	012600				MOV	(SP)+,R0
≠BR≡≡IN2≡≥	014576	000717				BR 	IN2		;CONTINUE READING
≤CRLF≡≥					2$:  	CRLF			;IF IT IS A CR, TYPE A CR AND LF
≤OUTSTR≡≥						OUTSTR CRLFX	;Carriage return, line feed.
≠MOV≡≡R0≡≡SP≡≥	014600	010046				MOV R0,-(SP)	;Save R0.  Who knows what was happening in it?
≠MOV≡≡R1≡≡SP≡≥	014602	010146				MOV R1,-(SP)	;Save R1.
≠MOV≡≡CRLFX≡≡R0≡≥	014604	012700	014266			MOV #CRLFX,R0	;Load up the string to be output
≠JSR≡≡PC≡≡TYPSTR≡≥	014610	004767	777264			JSR PC,TYPSTR	;Call the string output utility routine.
≠MOV≡≡SP≡≡R1≡≥	014614	012601				MOV (SP)+,R1	;Restore R1.
≠MOV≡≡SP≡≡R0≡≥	014616	012600				MOV (SP)+,R0	;Restore R0.
≠MOVB≡≡R1≡≡R0≡≥	014620	110120				MOVB	R1,(R0)+	;PUT A CR IN THE STRING
≠MOVB≡≡R0≡≥	014622	112710	000000			MOVB    #0,(R0)		;PUT IN A NULL CHARACTER
≠RTS≡≡PC≡≥	014626	000207				RTS	PC		;RETURN
≥	014630	000000			CCNT:	0
≠.BYTE≡≥	014632	   010		
≥	014633	   040		
≥	014634	   010		
≥	014635	   000			DBS:	.BYTE	10,40,10,0
≥					
≥					;System line buffers
≥					
≠.BLKW≡≥		014762			INBUF:	.BLKW	42.
≠.BLKW≡≥		015106			OUTBUF:	.BLKW	42.
≡INBUF≡≡INBUF≡≥	015106	014636			CURIN:	INBUF		;Current line pointer
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 12
	HAL PAL[HAL,HE]	PAGE 2.1 	Basic TTY input and output routines

≥					
≠.IFNZ≡≡MAP≡≥		000000			.IFNZ MAP
≥					    .INSRT MAP.PAL[HAL,HE]
≥					.ENDC
≥					
≠.INSRT≡≥					.INSRT LARGEB.PAL[HAL,HE]
≠COMMEN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 13
	LARGEB PAL[HAL,HE]	PAGE 1 	Basic TTY input and output routines

≥				COMMENT ⊗   VALID 00005 PAGES
≥				C REC  PAGE   DESCRIPTION
≥				C00001 00001
≥				C00002 00002	.SBTTL Free storage management:  FRINIT
≥				C00004 00003	  GTFREE
≥				C00009 00004	  RLFREE
≥				C00012 00005	  LBMAP
≥				C00014 ENDMK
≥					C⊗;
≠.SBTTL≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 14
	LARGEB PAL[HAL,HE]	PAGE 2 	Free storage management:  FRINIT

≥					.SBTTL Free storage management:  FRINIT
≥					
≥					; Assembly variables
≡FREL≠≥		005400			FREL = 5400		;Maximum = 40000 (IN WORDS!)
≥					
≥					; Free storage block
≠.EVEN≡≥		015110			.EVEN
≥	015110	000000			LBEVT:	0		;Large block interlock event
≡FREEST≡≡FREEST≡≥	015112	015116			FREEPT:	FREEST
≥	015114	777777				-1		;Left bdry tag is negative.
≡FREL≡≡FREL≡≥	015116	013000			FREEST:	FREL*2		;Beginning of free storage.  Boundary tag.
≠.BLKW≡≡FREL≡≥		030114				.BLKW	FREL-2	;
≡FREL≡≡FREL≡≥	030114	013000			FREEND:	FREL*2		;End of free storage.  Boundary tag.
≥	030116	777777				-1		;Right bdry tag is negative.
≥					
≥					; Routine to initialize storage.  Need only call if you think
≥					;	storage has been munged, or you want to start over for
≥					;	some reason.
≥					FRINIT:	;Initialization of the large block allocator
≤EVMAK≡≥						EVMAK		;Make a new large block interlock event
≥	030120	104004				104004
≠MOV≡≡SP≡≡LBEVT≡≥	030122	011667	764762			MOV (SP),LBEVT	;
≤EVSIG≡≥						EVSIG 		;Give it one signal
≤.ARG≡≥						  .ARG 
≠.LIF≡≥						    .LIF NB 
≥						      MOV ,-(SP)
≥	030126	104012				104012
≠MOV≡≡FREL≡≡FREEST≡≥	030130	012767	013000	764760		MOV #FREL*2,FREEST	;Lower inner tag
≠MOV≡≡FREL≡≡FREEND≡≥	030136	012767	013000	777750		MOV #FREL*2,FREEND	;Upper inner tag
≠MOV≡≡FREEST≡≡FREEPT≡≥	030144	012767	015116	764740		MOV #FREEST,FREEPT	;Roving free pointer
≠CMP≡≡FREEST≡≡FREEND≡≥	030152	026767	764736	777736		CMP FREEST-2,FREEND+2	;Do the two outer tags agree?
≠BNE≡≥	030160	001001				BNE 1$			;No.
≠RTS≡≡PC≡≥	030162	000207				RTS PC			;Yes.  Return.
≤HALERR≡≥					1$:	HALERR FRINMS
≠MOV≡≡FRINMS≡≡SP≡≥	030164	012746	030174			MOV #FRINMS,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	030170	004777	763616			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤ASCIE≡≥					FRINMS:	ASCIE /FRINIT FEARS FREE STORAGE HAS BEEN MUNGED/
≠.ASCIZ≡≥	030174	   106		
≥	030175	   122		
≥	030176	   111		
≥	030177	   116		
≥	030200	   111		
≥	030201	   124		
≥	030202	   040		
≥	030203	   106		
≥	030204	   105		
≥	030205	   101		
≥	030206	   122		
≥	030207	   123		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 15
	LARGEB PAL[HAL,HE]	PAGE 2.1 	Free storage management:  FRINIT

≥	030210	   040		
≥	030211	   106		
≥	030212	   122		
≥	030213	   105		
≥	030214	   105		
≥	030215	   040		
≥	030216	   123		
≥	030217	   124		
≥	030220	   117		
≥	030221	   122		
≥	030222	   101		
≥	030223	   107		
≥	030224	   105		
≥	030225	   040		
≥	030226	   110		
≥	030227	   101		
≥	030230	   123		
≥	030231	   040		
≥	030232	   102		
≥	030233	   105		
≥	030234	   105		
≥	030235	   116		
≥	030236	   040		
≥	030237	   115		
≥	030240	   125		
≥	030241	   116		
≥	030242	   107		
≥	030243	   105		
≥	030244	   104		
≥	030245	   000		
≥					       .ASCIZ /FRINIT FEARS FREE STORAGE HAS BEEN MUNGED/
≠.EVEN≡≥		030246			       .EVEN
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 16
	LARGEB PAL[HAL,HE]	PAGE 3 	Free storage management:  FRINIT

≥					;  GTFREE
≥					
≠COMMEN≡≥				  COMMENT ⊗
≥				  Routine to assign storage.  Amount of words requested in R0.
≥				 	Location of first word in block (not the boundary tag) returned
≥				 	in R0.
≥				   The boundary tag method described in Knuth I.2.5 is
≥				 	used.  Each block of storage has a boundary tag at
≥				 	each end, with identical contents:  The number
≥				 	of bytes in the whole area if available, and the opposite
≥				 	of that if busy.  Artificial busy areas above and below
≥				 	free storage.
≥				    Modified 10/76 by arg
≥					   ⊗
≥					
≤EVWAIT≡≥					GTFREE:	EVWAIT LBEVT	;Wait until we can enter critical section
≤.ARG≡≥						  .ARG LBEVT
≠.LIF≡≥						    .LIF NB LBEVT
≠MOV≡≡LBEVT≡≡SP≡≥	030246	016746	764636			      MOV LBEVT,-(SP)
≥	030252	104010				104010
≠MOV≡≡R2≡≡SP≡≥	030254	010246				MOV R2,-(SP)	;Save R2 on stack.
≠ASL≡≡R0≡≥	030256	006300				ASL R0		;Convert words to bytes
≠BGT≡≥	030260	003011				BGT 1$		;Asked for negative number of words?
≤PUNT≡≥						PUNT FRMS1	;Yes.  Complain.
≠MOV≡≡FRMS1≡≡SP≡≥	030262	012746	030510			MOV #FRMS1,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	030266	004777	763520			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠MOV≡≡PNTMES≡≡SP≡≥	030272	012746	064310			MOV #PNTMES,-(SP)	;Push the "Can't continue" message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	030276	004777	763510			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠BR≡≥	030302	000773				BR .-10			;Loop forever or until he gives up
≠.IFZ≡≡LBDEBU≡≥		000000			    .IFZ LBDEBUG
≠ADD≡≡R0≡≥	030304	062700	000004		1$:	ADD #4,R0	;Need 2 extra words for boundary tags
≥					    .IFF
≥					1$:	ADD #6,R0	;Need 2 extra words for boundary tags and one for trace
≥					    .ENDC
≠MOV≡≡FREEPT≡≡R1≡≥	030310	016701	764576			MOV FREEPT,R1	;R1 ← running LOC[LTAG[*]]
≠CMP≡≡R1≡≡FREEND≡≥	030314	020127	030114		FRTRY:	CMP R1,#FREEND	;Are we off the end of free storage?
≠BLOS≡≥	030320	101402				BLOS 2$		;No.
≠MOV≡≡FREEST≡≡R1≡≥	030322	012701	015116			MOV #FREEST,R1	;Yes.  Reset pointer to beginning.
≠TST≡≡R1≡≥	030326	005711			2$:	TST (R1)	;Is this area busy?  If so, its count is negative.
≠BLE≡≥	030330	003403				BLE 3$		;Yes.
≠CMP≡≡R1≡≡R0≡≥	030332	021100				CMP (R1),R0	;Do we have enough room here?
≠BGE≡≡FFOUND≡≥	030334	002020				BGE FFOUND	;Yes
≠BR≡≥	030336	000402				BR 4$		;No.
≠SUB≡≡R1≡≡R1≡≥	030340	161101			3$:	SUB (R1),R1	;Yes.  R1 ← LOC[LTAG[next] by subtraction.
≠BR≡≥	030342	000401				BR  5$
≠ADD≡≡R1≡≡R1≡≥	030344	061101			4$:	ADD (R1),R1	;R1 ← LOC[LTAG[next] by addition.
≠CMP≡≡R1≡≡FREEPT≡≥	030346	020167	764540		5$:	CMP R1,FREEPT	;Have we cycled all through free storage
≠BNE≡≡FRTRY≡≥	030352	001360				BNE FRTRY	;No.  Try again.
≤PUNT≡≥						PUNT FRMS2	;Yes.  No room!
≠MOV≡≡FRMS2≡≡SP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 17
	LARGEB PAL[HAL,HE]	PAGE 3.1 	Free storage management:  FRINIT

≥	030354	012746	030560			MOV #FRMS2,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	030360	004777	763426			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠MOV≡≡PNTMES≡≡SP≡≥	030364	012746	064310			MOV #PNTMES,-(SP)	;Push the "Can't continue" message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	030370	004777	763416			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠BR≡≥	030374	000773				BR .-10			;Loop forever or until he gives up
≠BEQ≡≡FEXACT≡≥	030376	001435			FFOUND:	BEQ FEXACT	;If 0, then exact fit.
≠MOV≡≡R1≡≡R2≡≥	030400	010102				MOV R1,R2	;Divide the found block into FOUND and HOLE.
≥								;Thus, R1 = LOC[LTAG[FOUND]].
≠ADD≡≡R0≡≡R2≡≥	030402	060002				ADD R0,R2	;R2 ← LOC[LTAG[HOLE]]
≠NEG≡≡R0≡≥	030404	005400				NEG R0		;R0 ← negative (busy) count of FOUND.
≠MOV≡≡R0≡≡R2≡≥	030406	010062	777776			MOV R0,-2(R2)	;RTAG[FOUND] ← new FOUND count.
≠MOV≡≡R0≡≡SP≡≥	030412	010046				MOV R0,-(SP)	;Save R0.
≠ADD≡≡R1≡≡R0≡≥	030414	061100				ADD (R1),R0	;R0 ← new HOLE count.
≠MOV≡≡R0≡≡R2≡≥	030416	010012				MOV R0,(R2)	;LTAG[HOLE] ← new HOLE count.
≠MOV≡≡R2≡≡FREEPT≡≥	030420	010267	764466			MOV R2,FREEPT	;Free pointer ← LOC[LTAG[HOLE]]
≠MOV≡≡R1≡≡R2≡≥	030424	010102				MOV R1,R2	;
≠TST≡≡R2≡≥	030426	005742				TST -(R2)	;
≠ADD≡≡R1≡≡R2≡≥	030430	061102				ADD (R1),R2	;R2 ← LOC[RTAG[HOLE]].
≠MOV≡≡R0≡≡R2≡≥	030432	010012				MOV R0,(R2)	;RTAG[HOLE] ← new HOLE count.
≠MOV≡≡SP≡≡R1≡≥	030434	012621				MOV (SP)+,(R1)+	;LTAG[FOUND] ← new FOUND count.
≠MOV≡≡R1≡≡R0≡≥	030436	010100			FRRET:	MOV R1,R0	;R0 (result) ← LOC[LTAG[FOUND]] + 1.
≠MOV≡≡R0≡≡R2≡≥	030440	016002	777776			MOV -2(R0),R2	;
≠NEG≡≡R2≡≥	030444	005402				NEG R2		;R2 ← count of length
≠ASR≡≡R2≡≥	030446	006202				ASR R2		; in words
≠SUB≡≡R2≡≥	030450	162702	000002			SUB #2,R2	; without the boundary words
≠.IFNZ≡≡LBDEBU≡≥		000000			    .IFNZ LBDEBUG
≥						MOV 2(SP),(R1)+	;Store the calling point in the area
≥					        TST (R0)+	;Usable area starts one word later
≥						DEC R2		;
≥					    .ENDC
≠CLR≡≡R1≡≥	030454	005021			6$:	CLR (R1)+	;Clear out a word
≠SOB≡≡R2≡≥	030456	077202				SOB R2,6$	;Until done
≠MOV≡≡SP≡≡R2≡≥	030460	012602				MOV (SP)+,R2	;Restore R2
≤EVSIG≡≥						EVSIG LBEVT	;Can let others in now.
≤.ARG≡≥						  .ARG LBEVT
≠.LIF≡≥						    .LIF NB LBEVT
≠MOV≡≡LBEVT≡≡SP≡≥	030462	016746	764422			      MOV LBEVT,-(SP)
≥	030466	104012				104012
≠RTS≡≡PC≡≥	030470	000207				RTS PC		;Done.
≠MOV≡≡R1≡≡R2≡≥	030472	010102			FEXACT:	MOV R1,R2	;
≠ADD≡≡R1≡≡R2≡≥	030474	061102				ADD (R1),R2	;R2 ← LOC[RTAG[FOUND]]+2
≠MOV≡≡R2≡≡FREEPT≡≥	030476	010267	764410			MOV R2,FREEPT	;Free pointer ← LOC[next block]
≠NEG≡≡R1≡≥	030502	005421				NEG (R1)+	;LTAG[FOUND] ← new (busy) count.
≠NEG≡≡R2≡≥	030504	005442				NEG -(R2)	;RTAG[FOUND] ← new (busy) count.
≠BR≡≡FRRET≡≥	030506	000753				BR FRRET	;Ready to return
≤ASCIE≡≥					FRMS1:	ASCIE </GTFREE: R0 HAS BAD REQUEST WORD LENGTH/>
≠.ASCIZ≡≥	030510	   107		
≥	030511	   124		
≥	030512	   106		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 18
	LARGEB PAL[HAL,HE]	PAGE 3.2 	Free storage management:  FRINIT

≥	030513	   122		
≥	030514	   105		
≥	030515	   105		
≥	030516	   072		
≥	030517	   040		
≥	030520	   122		
≥	030521	   060		
≥	030522	   040		
≥	030523	   110		
≥	030524	   101		
≥	030525	   123		
≥	030526	   040		
≥	030527	   102		
≥	030530	   101		
≥	030531	   104		
≥	030532	   040		
≥	030533	   122		
≥	030534	   105		
≥	030535	   121		
≥	030536	   125		
≥	030537	   105		
≥	030540	   123		
≥	030541	   124		
≥	030542	   040		
≥	030543	   127		
≥	030544	   117		
≥	030545	   122		
≥	030546	   104		
≥	030547	   040		
≥	030550	   114		
≥	030551	   105		
≥	030552	   116		
≥	030553	   107		
≥	030554	   124		
≥	030555	   110		
≥	030556	   000		
≥					       .ASCIZ /GTFREE: R0 HAS BAD REQUEST WORD LENGTH/
≠.EVEN≡≥		030560			       .EVEN
≤ASCIE≡≥					FRMS2:	ASCIE /FREE STORAGE EXHAUSTED/
≠.ASCIZ≡≥	030560	   106		
≥	030561	   122		
≥	030562	   105		
≥	030563	   105		
≥	030564	   040		
≥	030565	   123		
≥	030566	   124		
≥	030567	   117		
≥	030570	   122		
≥	030571	   101		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 19
	LARGEB PAL[HAL,HE]	PAGE 3.3 	Free storage management:  FRINIT

≥	030572	   107		
≥	030573	   105		
≥	030574	   040		
≥	030575	   105		
≥	030576	   130		
≥	030577	   110		
≥	030600	   101		
≥	030601	   125		
≥	030602	   123		
≥	030603	   124		
≥	030604	   105		
≥	030605	   104		
≥	030606	   000		
≥					       .ASCIZ /FREE STORAGE EXHAUSTED/
≠.EVEN≡≥		030610			       .EVEN
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 20
	LARGEB PAL[HAL,HE]	PAGE 4 	Free storage management:  FRINIT

≥					;  RLFREE
≥					
≥					; Routine to release free storage.  R0=LOC[LTAG[BLOCK]] + 1.
≥					; Call the currently released block BLOCK, the adjacent one
≥					;	below LOW, and the adjacent one above HIGH.
≤EVWAIT≡≥					RLFREE:	EVWAIT LBEVT	;Wait for our turn in critical code.
≤.ARG≡≥						  .ARG LBEVT
≠.LIF≡≥						    .LIF NB LBEVT
≠MOV≡≡LBEVT≡≡SP≡≥	030610	016746	764274			      MOV LBEVT,-(SP)
≥	030614	104010				104010
≠.IFNZ≡≡LBDEBU≡≥		000000			    .IFNZ LBDEBUG
≥						TST -(R0)	;Go past initial word
≥					    .ENDC
≠TST≡≡R0≡≥	030616	005740				TST -(R0)	;Check block size
≠BLT≡≥	030620	002411				BLT 1$		;Reasonable?
≤PUNT≡≥						PUNT RLMS1	;No.  Already available space.
≠MOV≡≡RLMS1≡≡SP≡≥	030622	012746	031002			MOV #RLMS1,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	030626	004777	763160			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠MOV≡≡PNTMES≡≡SP≡≥	030632	012746	064310			MOV #PNTMES,-(SP)	;Push the "Can't continue" message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	030636	004777	763150			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠BR≡≥	030642	000773				BR .-10			;Loop forever or until he gives up
≠MOV≡≡R0≡≡R1≡≥	030644	010001			1$:	MOV R0,R1	;R1 ← LOC[LTAG[BLOCK]]
≠SUB≡≡R0≡≡R0≡≥	030646	161000				SUB (R0),R0	;R0 ← LOC[LTAG[HIGH]]
≠CMP≡≡R1≡≡R0≡≥	030650	021160	777776			CMP (R1),-2(R0)	;Do the two bdry tags agree?
≠BEQ≡≥	030654	001411				BEQ 2$		;
≤PUNT≡≥						PUNT RLMS2	;No.  Storage munged!!
≠MOV≡≡RLMS2≡≡SP≡≥	030656	012746	031052			MOV #RLMS2,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	030662	004777	763124			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠MOV≡≡PNTMES≡≡SP≡≥	030666	012746	064310			MOV #PNTMES,-(SP)	;Push the "Can't continue" message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	030672	004777	763114			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠BR≡≥	030676	000773				BR .-10			;Loop forever or until he gives up
≠NEG≡≡R1≡≥	030700	005411			2$:	NEG (R1)	;Count is now positive in LTAG[BLOCK].
≠TST≡≡R1≡≥	030702	005761	777776			TST -2(R1)	;Is LOW available?
≠BLT≡≡MERGR≡≥	030706	002416				BLT MERGR	;No.  Cannot merge left.
≠CMP≡≡FREEPT≡≡R1≡≥	030710	026701	764176			CMP FREEPT,R1	;Will FREEPT point into a vacuum?
≠BNE≡≥	030714	001002				BNE 3$		;No.
≠MOV≡≡R0≡≡FREEPT≡≥	030716	010067	764170			MOV R0,FREEPT	;Yes.  Reset FREEPT ← LOC[LTAG[HIGH]]
≠ADD≡≡R1≡≡R1≡≥	030722	066111	777776		3$:	ADD -2(R1),(R1)	;Yes.  LTAG[BLOCK] ← New count
≠MOV≡≡R1≡≡R0≡≥	030726	011160	777776			MOV (R1),-2(R0)	;RTAG[BLOCK] ← New count
≠MOV≡≡R0≡≡R1≡≥	030732	010001				MOV R0,R1	;
≠SUB≡≡R1≡≡R1≡≥	030734	166101	777776			SUB -2(R1),R1	;R1 ← LOC[LTAG[LOW]]
≠MOV≡≡R0≡≡R1≡≥	030740	016011	777776			MOV -2(R0),(R1)	;LTAG[LOW] ← New count
≥								;At this point, call LOW&BLOCK = BLOCK.
≠TST≡≡R0≡≥	030744	005710			MERGR:	TST (R0)	;Is HIGH available?
≠BLT≡≡RLRET≡≥	030746	002407				BLT RLRET	;No.  Prepare to return.
≠ADD≡≡R0≡≡R1≡≥	030750	061011				ADD (R0),(R1)	;LTAG[BLOCK] ← New count
≠CMP≡≡FREEPT≡≡R0≡≥	030752	026700	764134			CMP FREEPT,R0	;Will FREEPT point into a vacuum?
≠BNE≡≥	030756	001002				BNE 4$		;No.
≠MOV≡≡R1≡≡FREEPT≡≥	030760	010167	764126			MOV R1,FREEPT	;Yes.  Reset FREEPT ← LOC[LTAG[BLOCK]]
≠ADD≡≡R0≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 21
	LARGEB PAL[HAL,HE]	PAGE 4.1 	Free storage management:  FRINIT

≥	030764	061000			4$:	ADD (R0),R0	;R0 ← LOC[RTAG[HIGH]] + 2
≥								;At this point, call BLOCK&HIGH = BLOCK.
≠MOV≡≡R1≡≡R0≡≥	030766	011160	777776		RLRET:	MOV (R1),-2(R0)	;RTAG[BLOCK] ← New count
≤EVSIG≡≥						EVSIG LBEVT	;Let others into critical section now.
≤.ARG≡≥						  .ARG LBEVT
≠.LIF≡≥						    .LIF NB LBEVT
≠MOV≡≡LBEVT≡≡SP≡≥	030772	016746	764112			      MOV LBEVT,-(SP)
≥	030776	104012				104012
≠RTS≡≡PC≡≥	031000	000207				RTS PC		;Done.
≥					
≤ASCIE≡≥					RLMS1:	ASCIE /RLFREE: FREEING ALREADY AVAILABLE SPACE/
≠.ASCIZ≡≥	031002	   122		
≥	031003	   114		
≥	031004	   106		
≥	031005	   122		
≥	031006	   105		
≥	031007	   105		
≥	031010	   072		
≥	031011	   040		
≥	031012	   106		
≥	031013	   122		
≥	031014	   105		
≥	031015	   105		
≥	031016	   111		
≥	031017	   116		
≥	031020	   107		
≥	031021	   040		
≥	031022	   101		
≥	031023	   114		
≥	031024	   122		
≥	031025	   105		
≥	031026	   101		
≥	031027	   104		
≥	031030	   131		
≥	031031	   040		
≥	031032	   101		
≥	031033	   126		
≥	031034	   101		
≥	031035	   111		
≥	031036	   114		
≥	031037	   101		
≥	031040	   102		
≥	031041	   114		
≥	031042	   105		
≥	031043	   040		
≥	031044	   123		
≥	031045	   120		
≥	031046	   101		
≥	031047	   103		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 22
	LARGEB PAL[HAL,HE]	PAGE 4.2 	Free storage management:  FRINIT

≥	031050	   105		
≥	031051	   000		
≥					       .ASCIZ /RLFREE: FREEING ALREADY AVAILABLE SPACE/
≠.EVEN≡≥		031052			       .EVEN
≤ASCIE≡≥					RLMS2:	ASCIE /RLFREE: END TAGS DISAGREE/
≠.ASCIZ≡≥	031052	   122		
≥	031053	   114		
≥	031054	   106		
≥	031055	   122		
≥	031056	   105		
≥	031057	   105		
≥	031060	   072		
≥	031061	   040		
≥	031062	   105		
≥	031063	   116		
≥	031064	   104		
≥	031065	   040		
≥	031066	   124		
≥	031067	   101		
≥	031070	   107		
≥	031071	   123		
≥	031072	   040		
≥	031073	   104		
≥	031074	   111		
≥	031075	   123		
≥	031076	   101		
≥	031077	   107		
≥	031100	   122		
≥	031101	   105		
≥	031102	   105		
≥	031103	   000		
≥					       .ASCIZ /RLFREE: END TAGS DISAGREE/
≠.EVEN≡≥		031104			       .EVEN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 23
	LARGEB PAL[HAL,HE]	PAGE 5 	Free storage management:  FRINIT

≥					;  LBMAP
≥					
≥					LBMAP:
≠COMMEN≡≥					COMMENT ⊗ Prints the free storage map.  ⊗
≠MOV≡≡R0≡≡SP≡≥	031104	010046				MOV R0,-(SP)	;Save R0
≠MOV≡≡R1≡≡SP≡≥	031106	010146				MOV R1,-(SP)	;Save R1
≠MOV≡≡R2≡≡SP≡≥	031110	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡FREEST≡≡R2≡≥	031112	012702	015116			MOV #FREEST,R2	;R2 ← LOC[first block]
≠TST≡≡R2≡≥	031116	005712			1$:	TST (R2)	;Used or free?
≠BGE≡≥	031120	002021				BGE 3$		;Free.
≠CMP≡≡R2≡≡FREEND≡≥	031122	020227	030114			CMP R2,#FREEND	;Used.  At the end yet?
≠BLT≡≥	031126	002404				BLT 2$		;No
≠MOV≡≡SP≡≡R2≡≥	031130	012602				MOV (SP)+,R2	;Yes. Restore R2
≠MOV≡≡SP≡≡R1≡≥	031132	012601				MOV (SP)+,R1	;Restore R1
≠MOV≡≡SP≡≡R0≡≥	031134	012600				MOV (SP)+,R0	;Restore R0
≠RTS≡≡PC≡≥	031136	000207				RTS PC		;Done
≠MOV≡≡CRLFX≡≡R0≡≥	031140	012700	014266		2$:	MOV #CRLFX,R0	;
≠JSR≡≡PC≡≡TYPSTR≡≥	031144	004767	762730			JSR PC,TYPSTR	;
≠.IFNZ≡≡LBDEBU≡≥		000000			    .IFNZ LBDEBUG
≥						MOV 2(R2),R0	;Print who.
≥						JSR PC,TYPOCT	;
≥						MOV #' ,R0	;
≥						JSR PC,TYPCHR	;
≥					    .ENDC
≠MOV≡≡R2≡≡R0≡≥	031150	011200				MOV (R2),R0	;Print how much
≠NEG≡≡R0≡≥	031152	005400				NEG R0		;
≠JSR≡≡PC≡≡TYPOCT≡≥	031154	004767	762750			JSR PC,TYPOCT	;
≠SUB≡≡R2≡≡R2≡≥	031160	161202				SUB (R2),R2	;Move to next block
≠BR≡≥	031162	000755				BR 1$		;Treat next block
≠ADD≡≡R2≡≡R2≡≥	031164	061202			3$:	ADD (R2),R2	;Move past free block
≠BR≡≥	031166	000753				BR 1$		;Treat next block
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 24
	HAL PAL[HAL,HE]	PAGE 2.2 	Free storage management:  FRINIT

≥					
≤PDBLK≡≥					MAINBL:	PDBLK 210,S	;Makes a process descriptor for main process
≠.IF≡≥						.IF NB S
≠.IF≡≥						  .IF IDN <S>,<D>
≥						    .W.==UFPUSE+UDPUSE
≥						    .L.==66
≥						  .IFF
≡UFPUSE≡≡.W.≠≥		100000				    .W.==UFPUSE
≡.L.≠≥		000036				    .L.==36
≥						  .ENDC
≥						.IFF
≥						  .W.==0
≥						  .L.==0
≥						.ENDC
≠.WORD≡≡.W.≡≥	031170	100000				.WORD .W.
≠.WORD≡≡UFEC≡≡UST0≡≡.L.≡≥	031172	000520				.WORD <UFEC-UST0>+.L.+<2*210>
≠.BLKB≡≡UIMAP≡≡USKMIN≡≥		031212				.BLKB UIMAP-USKMIN
≠.WORD≡≥	031212	000376				.WORD 376
≠.WORD≡≥	031214	000376				.WORD 376
≠.BLKB≡≡UFEC≡≡PDBR0≡≥		031232				.BLKB UFEC-PDBR0
≠.BLKB≡≡.L.≡≥		031710				.BLKB 2*210+.L.
≥					
≠.IFNZ≡≡SMALLB≡≥		000001			.IFNZ SMALLB		;Small block allocator
≠.INSRT≡≥					    .INSRT SMALLB.PAL[HAL,HE]
≠COMMEN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 25
	SMALLB PAL[HAL,HE]	PAGE 1 	Free storage management:  FRINIT

≥				COMMENT ⊗   VALID 00018 PAGES
≥				C REC  PAGE   DESCRIPTION
≥				C00001 00001
≥				C00003 00002	.SBTTL SMALL BLOCK ALLOCATOR
≥				C00008 00003	 Definitions of fields
≥				C00011 00004	 DEFSPC
≥				C00013 00005	 DATA AREA
≥				C00014 00006	 MAPPTR, MKRTJM, MARKR0, LNKMTH
≥				C00022 00007	 MARKPH, MKROUT
≥				C00024 00008	ROUTINE CMPSP,<SPC>
≥				C00028 00009	ROUTINE COMPACT
≥				C00030 00010	 SWEEP
≥				C00034 00011	 GC, NOGC, YESGC, NOCMP, YESCMP
≥				C00037 00012	 GETSBK, GETBLK, GETSID, PTRSID
≥				C00041 00013	 FREBLK, FRESBK
≥				C00043 00014	 NEWSPC, SETSPC
≥				C00045 00015	 ADDBUF
≥				C00048 00016	 Standard spaces, SBINIT, Marking methods: MCELL, MARKQ
≥				C00054 00017	.IFNZ	SMBDBG		Test routine
≥				C00056 00018	 Known bugs
≥				C00058 ENDMK
≥					C⊗;
≠.SBTTL≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 26
	SMALLB PAL[HAL,HE]	PAGE 2 	SMALL BLOCK ALLOCATOR

≥					.SBTTL SMALL BLOCK ALLOCATOR
≥					;Coded by RHT 9-Sept-1974
≥					;Debugged & fixed by ARG 11/76
≥					
≡SMBDBG≠≥		000000			SMBDBG == 0	;1 => WE ARE DEBUGGING (PUT IN TEST ROUTINE)
≥					
≠COMMEN≡≥				COMMENT ⊗
≥				
≥				Overview: The basic idea is to break up large blocks of storage into
≥				smaller, fixed size blocks, and then administer them.  The routines
≥				given here provide a facility whereby a user can have a number of
≥				different "spaces" of fixed size blocks.  Each space is described by
≥				an approximately 10 word space descriptor.  All these space
≥				descriptors are linked together on a big chain (SIDLST), and each
≥				space is assumed to have asociated with it a unique 8-bit number
≥				(thus allowing up to 256 spaces).  Each space descriptor owns a
≥				linked list of buffers; each buffer contains a number of blocks.
≥				Each space may be either collectable or uncollectable.  Any block may
≥				be released explicitly, although if the space is collectable, this
≥				may be unwise.  Also, collectable spaces are compacted by the
≥				garbage collector.  As an efficiency measure, the first few indices
≥				[of what? - RF] (now, 1-10) are also kept in a table (SIDTBL). 
≥				 
≥				 Blocks are allocated by the routines GETBLK & GETSBK:
≥				 
≥				 	MOV	#IDCODE,R0	 ;IDCODE is the 8-bit code for a space
≥				 	JSR	PC,GETBLK	 ;
≥				 
≥				 	MOV	#SPCDSC,R0	 ;SPCDSC is the address of the space
≥				 	JSR	PC,GETSBK	 ;descriptor
≥				 
≥				In either case, a pointer to a new block is returned in R0.  If need
≥				be, the free space routine will call the garbage collector to get
≥				more space or (if the space is not collectable or garbage collection
≥				is disabled) it will call the large block routines to get another
≥				buffer.  If garbage collection fails to produce a goodly surplus of
≥				blocks for some space, then additional buffers of new blocks will be
≥				obtained. 
≥				 
≥				Each small block has the following format:
≥				
≥				 		TAG,,ID		 tag is used in garbage collecting
≥				 	R0 →→	WORD 0		 this is the word pointed to by getblk
≥				 		:
≥				 		WORD n
≥				 
≥				Blocks are zeroed before being returned.  Although this is sometimes
≥				a bit extra overhead, it does prevent bugs and avoids the necessity
≥				for explicit clears all over the place. 
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 27
	SMALLB PAL[HAL,HE]	PAGE 2.1 	SMALL BLOCK ALLOCATOR

≥				 
≥				Blocks are freed by the routines FREBLK & FRESBK:
≥				 
≥				 	MOV	BLOCK,R0	 ;R0 ← block to free
≥				 	JSR	PC,FREBLK
≥				 
≥				 	MOV	BLOCK,R0	 ;R0 ← block to free
≥				 	MOV	#SPCDSC,R1	 ;R1 ← space descriptor
≥				 	JSR	PC,FRESBK
≥				 
≥				The macro 
≥				 	 DEFSPC ID,MMRT,SZ,NPB,GCF,NMN,NPC
≥				may be used to declare compiled-in space descriptors.  Please see the
≥				comment on routine MAPPTR for additional instuctions for declaring
≥				spaces. 
≥				
≥				NOTE:  These routines are set up to allow for compacting of 
≥				free space & release of excess buffer blocks.  However, the routine
≥				for doing the actual release of excess blocks is not included yet
≥				although the place it is to go is clearly marked (in COMPACT).  Therefore,
≥				it is suggested that the flag CMPOK be left OFF for the time being.
≥					
≥					Release routine added (to SWP.) 11/76 ARG 
≥					⊗
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 28
	SMALLB PAL[HAL,HE]	PAGE 3 	SMALL BLOCK ALLOCATOR

≥					; Definitions of fields
≥					
≥					;SPACE DESCRIPTOR
≥					
≡II≠≥		000000				II == 0
≤XX≡≥						XX	IDFLAG	;Actually a byte; gets put in the ID part of tag word
≠.IFDF≡≡IDFLAG≡≥						   .IFDF IDFLAG
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using IDFLAG in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡IDFLAG≠≥		000000				    IDFLAG == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX	MAPRTN	;Routine to be called when marking
≠.IFDF≡≡MAPRTN≡≥						   .IFDF MAPRTN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using MAPRTN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡MAPRTN≠≥		000002				    MAPRTN == II
≡II≡≡II≠≥		000004				    II == II+2
≤XX≡≥						XX	SIZE	;How many words for a value cell in this type block.
≠.IFDF≡≡SIZE≡≥						   .IFDF SIZE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using SIZE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡SIZE≠≥		000004				    SIZE == II
≡II≡≡II≠≥		000006				    II == II+2
≤XX≡≥						XX	NPERB	;Number of blocks per buffer
≠.IFDF≡≡NPERB≡≥						   .IFDF NPERB
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NPERB in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NPERB≠≥		000006				    NPERB == II
≡II≡≡II≠≥		000010				    II == II+2
≤XX≡≥						XX	GCFG	;Set if this is a collectable area
≠.IFDF≡≡GCFG≡≥						   .IFDF GCFG
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using GCFG in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡GCFG≠≥		000010				    GCFG == II
≡II≡≡II≠≥		000012				    II == II+2
≤XX≡≥						XX	NMIN	;Min number of free blocks to be returned by GC
≠.IFDF≡≡NMIN≡≥						   .IFDF NMIN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NMIN in two ways!!!
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 29
	SMALLB PAL[HAL,HE]	PAGE 3.1 	SMALL BLOCK ALLOCATOR

≥						       .ENDC
≥						   .ENDC
≡II≡≡NMIN≠≥		000012				    NMIN == II
≡II≡≡II≠≥		000014				    II == II+2
≤XX≡≥						XX	NPCT	;Min % of free blocks to be returned by GC
≠.IFDF≡≡NPCT≡≥						   .IFDF NPCT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NPCT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NPCT≠≥		000014				    NPCT == II
≡II≡≡II≠≥		000016				    II == II+2
≤XX≡≥						XX	NXTSID	;Next space descriptor on ID chain
≠.IFDF≡≡NXTSID≡≥						   .IFDF NXTSID
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NXTSID in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NXTSID≠≥		000016				    NXTSID == II
≡II≡≡II≠≥		000020				    II == II+2
≤XX≡≥						XX	FFREE	;List of free blocks
≠.IFDF≡≡FFREE≡≥						   .IFDF FFREE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using FFREE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡FFREE≠≥		000020				    FFREE == II
≡II≡≡II≠≥		000022				    II == II+2
≤XX≡≥						XX	FSTBUF	;Oldest buffer
≠.IFDF≡≡FSTBUF≡≥						   .IFDF FSTBUF
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using FSTBUF in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡FSTBUF≠≥		000022				    FSTBUF == II
≡II≡≡II≠≥		000024				    II == II+2
≤XX≡≥						XX	LSTBUF	;Newest buffer
≠.IFDF≡≡LSTBUF≡≥						   .IFDF LSTBUF
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using LSTBUF in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡LSTBUF≠≥		000024				    LSTBUF == II
≡II≡≡II≠≥		000026				    II == II+2
≤XX≡≥						XX	NALLOC	;Number of blocks allocated
≠.IFDF≡≡NALLOC≡≥						   .IFDF NALLOC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NALLOC in two ways!!!
≥						       .ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 30
	SMALLB PAL[HAL,HE]	PAGE 3.2 	SMALL BLOCK ALLOCATOR

≥						   .ENDC
≡II≡≡NALLOC≠≥		000026				    NALLOC == II
≡II≡≡II≠≥		000030				    II == II+2
≤XX≡≥						XX	NFREE	;Number of blocks free
≠.IFDF≡≡NFREE≡≥						   .IFDF NFREE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NFREE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NFREE≠≥		000030				    NFREE == II
≡II≡≡II≠≥		000032				    II == II+2
≡II≡≡SPCHDR≠≥		000032				SPCHDR == II	;Number of bytes in a space descriptor
≥					
≥					; BUFFER HEADER
≡II≠≥		000000				II == 0
≤XX≡≥						XX	NXTBUF	;Next buffer in this space
≠.IFDF≡≡NXTBUF≡≥						   .IFDF NXTBUF
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NXTBUF in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NXTBUF≠≥		000000				    NXTBUF == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX	PRVBUF	;Previous buffer in this space
≠.IFDF≡≡PRVBUF≡≥						   .IFDF PRVBUF
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using PRVBUF in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡PRVBUF≠≥		000002				    PRVBUF == II
≡II≡≡II≠≥		000004				    II == II+2
≤XX≡≥						XX	LSTBLK	;Address of last block in this buffer
≠.IFDF≡≡LSTBLK≡≥						   .IFDF LSTBLK
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using LSTBLK in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡LSTBLK≠≥		000004				    LSTBLK == II
≡II≡≡II≠≥		000006				    II == II+2
≤XX≡≥						XX	FSTBLK	;Address of first block in this buffer, word 0.
≠.IFDF≡≡FSTBLK≡≥						   .IFDF FSTBLK
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using FSTBLK in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡FSTBLK≠≥		000006				    FSTBLK == II
≡II≡≡II≠≥		000010				    II == II+2
≡II≡≡BUFHDR≠≥		000010				BUFHDR == II	;Number of bytes in a buffer header
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 31
	SMALLB PAL[HAL,HE]	PAGE 3.3 	SMALL BLOCK ALLOCATOR

≥					; SMALL BLOCK
≡II≠≥		000000				II == 0
≡TAG≠≥		777777				TAG == -1	; ≠ 0 means in use (used by GC)
≡TAGID≠≥		777776				TAGID == -2	;Holds an "ID" for this record
≤XX≡≥						XX	WORD0	;First data word
≠.IFDF≡≡WORD0≡≥						   .IFDF WORD0
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using WORD0 in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡WORD0≠≥		000000				    WORD0 == II
≡II≡≡II≠≥		000002				    II == II+2
≥					                        ;Note that if this block is free, the first data
≥					                        ;word is used to maintain a list of free
≥					                        ;blocks. 
≥					
≥					; GC METHODS
≡II≠≥		000000				II == 0
≤XX≡≥						XX	METH	;Address of routine to call
≠.IFDF≡≡METH≡≥						   .IFDF METH
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using METH in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡METH≠≥		000000				    METH == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX	NXTMTH	;Next CG method on chain
≠.IFDF≡≡NXTMTH≡≥						   .IFDF NXTMTH
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NXTMTH in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NXTMTH≠≥		000002				    NXTMTH == II
≡II≡≡II≠≥		000004				    II == II+2
≥					
≥					; Marking method macro
≠.MACRO≡≤MMETH≠≥					       .MACRO MMETH ROUT
≥						ROUT
≥						0
≥					       .ENDM
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 32
	SMALLB PAL[HAL,HE]	PAGE 4 	SMALL BLOCK ALLOCATOR

≥					; DEFSPC
≥					
≥					; Assemble-time spaces
≠.IF2≡≥					       .IF2
≡SIDCHN≡≡SIDHED≠≥		035050				SIDHED == SIDCHN ;Sets SIDHED to the final value of SIDCHN
≥					       .ENDC
≥					
≡SIDCNT≠≥		000000			SIDCNT == 0		;Number of assembled-in space descriptors
≡SIDCHN≠≥		000000			SIDCHN == 0		;Linkage for assembled-in space descriptors
≥					
≠COMMEN≡≥				COMMENT ⊗ Declare assembled-in space descriptors: Makes a space
≥				descriptor.  ID is given the number of the space.  MMRT is the map
≥				routine, SZ the size, NPB the number of blocks per buffer, GCF is set
≥				if the area is not to be collected, NMN is the minimum number of free
≥				blocks that GC should return, NPC is the minimum percent of free
≥					blocks that GC should return.  ⊗
≥					
≠.MACRO≡≤DEFSPC≠≥					.MACRO DEFSPC ID,MMRT,SZ,NPB,GCF,NMN,NPC
≥					    .IFNDF ID
≥						SIDCNT==SIDCNT+1
≥						ID==SIDCNT
≥					    .ENDC
≥					    II==.
≥					    .BLKW SPCHDR/2
≥						TT	IDFLAG,ID
≥						TT	MAPRTN,MMRT
≥						TT	SIZE,SZ
≥						TT	NPERB,NPB
≥						TT	GCFG,GCF
≥						TT	NMIN,NMN
≥						TT	NPCT,NPC
≥						TT	NXTSID,SIDCHN
≥						TT	FFREE,0
≥						TT	FSTBUF,0
≥						TT	LSTBUF,0
≥						TT	NALLOC,0
≥						TT	NFREE,0
≥					    SIDCHN == II
≥					    .=II+SPCHDR
≥					      .IF2
≥						.IFGE MAXIDF-ID
≥						  PUTLOC <ID*2 + SIDTBL>,SIDCHN
≥						.ENDC
≥					      .ENDC
≥					.ENDM
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 33
	SMALLB PAL[HAL,HE]	PAGE 5 	SMALL BLOCK ALLOCATOR

≥					; DATA AREA
≥					
≥	031710	000000			SBEVT:	0		;Interlocking event
≥	031712	000000			MMETHS:	0		;Header of list of marking methods
≥	031714	000000			GCOK:	0		;0 => GC is OK; else count of those opposed to it.
≥	031716	000000			GCDONE: 0		;Count of times GC performed
≥	031720	000000			CMPOK:	0		;0 => compacting is OK; else count of those opposed
≥					SIDLST:			;List of space descriptor blocks
≠.IF1≡≥						.IF1		;Let pass 2 of assemble fix this up
≥							0
≥						.ENDC
≠.IF2≡≥						.IF2
≡SIDHED≡≡SIDHED≡≥	031722	035050					SIDHED
≥						.ENDC
≥					
≡MAXIDF≠≥		000030			MAXIDF == 30		;Max index into SIDTBL
≥	031724	000000			SIDTBL:	0		;Table of space descriptors for efficiency
≠.BLKB≡≡MAXIDF≡≥		031756				.BLKB MAXIDF
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 34
	SMALLB PAL[HAL,HE]	PAGE 6 	SMALL BLOCK ALLOCATOR

≥					; MAPPTR, MKRTJM, MARKR0, LNKMTH
≥					
≤ROUTIN≡≥					ROUTINE MAPPTR,<ROUT>	
≠.IFNB≡≥					           .IFNB ROUT
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<ROUT>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<ROUT>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡ROUT≡≥					                  .IFDF ROUT
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for ROUT
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡ROUT≠≥		000002			                   ROUT == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					MAPPTR:
≥					 
≠COMMEN≡≥				COMMENT ⊗ ROUT takes a single parameter (in R0) which is a pointer to
≥				a small block.  It returns (in R0) a pointer value which is to be
≥				stored back in the pointer cell.  This allows MAPPTR to be called
≥				twice to do essentially different things.  The first time, during
≥				marking, ROUT will be MKROUT.  The second time, during compacting,
≥				it will be something else. 
≥				
≥				MAPPTR runs down a list of "marking methods" (MMETHS).  Each method
≥				is assumed to be responsible for some batch of "top level" pointers
≥				(i.e., variables in the user's program that point to small blocks). 
≥				For each pointer it finds, a method should call the routine MARKR0
≥				(via JSR PC).  Thus, each marking method should have the form
≥				
≥				 	METH:	R←#<first pointer>
≥				 		WHILE R≠NULL DO
≥				 			BEGIN
≥				 			R0←(R);
≥				 			JSR PC,MARKR0;
≥				 			(R)←R0;
≥				 			R←#<next pointer>;
≥				 			END;
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 35
	SMALLB PAL[HAL,HE]	PAGE 6.1 	SMALL BLOCK ALLOCATOR

≥				 		RETURN;
≥				 
≥				MARKR0 determines the type of the record (finds its space descriptor).
≥				It then does a 
≥				
≥				 		JSR	PC,@MAPRTN(<space>)
≥				
≥				MAPRTN takes as a parameter a single block pointer in R0 & returns(in
≥				R0) a pointer to the same block (In the case of compacting,
≥				this may be a different value).  The routine is responsible for
≥				"marking" the block and any pointer subfields of the block.  If there
≥				are no pointer subfields, then the system routine MKRTJM ( JMP
≥				@ROUT(RF) ) may be used.  If there are pointer subfields, then the
≥				mark routine needs to be more complicated:
≥				 
≥				 		IF TAG(R0) THEN RTS PC;	comment if block handled, then return;
≥				 		JSR	PC,@2(RF);	comment calls ROUT;
≥				 		PUSH R;
≥				 		R←R0;
≥				 		∀ <field> | <field> is a pointer subfield of R DO
≥				 			BEGIN
≥				 			R0←<field>
≥				 			JSR	PC,MARKR0;
≥				 			<field>←R0;
≥				 			end;
≥				 		R0←R;
≥				 		POP R;
≥				 		RTS PC;
≥				 
≥				Note: it may be a good idea to change the conventions here a bit to
≥				(1) pass a pointer at a record pointer & (2) let markr0 assume
≥				responsibility for storing the updated pointer.  The advantage of
≥				such a course is that it allows iterative marking of long lists, thus
≥				avoiding possible pdl overflows. (P.S. RHT loses again. Unless some
≥				totally new data structures are added to the runtime system everything
≥				is fine as is. I've changed some current routine (e.g MCELL pg16) to
≥				be iterative. They were recursive. ----  arg  11/76 )
≥				
≥				
≥				NOTE: There is a BUG in COMPACT.  The test on the tag inside the
≥				maprtn may cause a record to be skipped over that has pointer
≥				subfields to garbage (ie moved records).  Fix this later.
≥				LEAVE CMPOK OFF 					RHT
≥				
≥				FURTHER NOTE: RHT is out to lunch here. We don't have any data types
≥				allocated by the small blocks allocator where the above becomes a problem.
≥				Cells might have been a problem, but they are only used to create
≥				simple lists. His compacter had several other bugs which are now
≥				fixed. CMPOK is now ON.
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 36
	SMALLB PAL[HAL,HE]	PAGE 6.2 	SMALL BLOCK ALLOCATOR

≥										ARG   11/76
≥				
≥				EXAMPLE: Consider a CONS cell:
≥				
≥				DEFSPC	CNSCLL,CNSMRK,2,100,0,40,20
≥					II == 0
≥					XX	CAR
≥					XX	CDR
≥				
≥				; This is the map routine associated with the CONS cell space:
≥				CNSMRK:	TSTB	TAG(R0)		
≥					BNE	CNSM.X
≥					JSR	PC,@2(RF)	; calls ROUT
≥					MOV	R2,-(SP)	; 
≥					MOV	R0,R2		;SAVE RETN VALUE
≥					MOV	CAR(R2),R0	; MARK CAR
≥					JSR	PC,MARKR0
≥					MOV	R0,CAR(R2)
≥					MOV	CDR(R2),R0	;MARK CDR
≥					JSR	PC,MARKR0
≥					MOV	R0,CDR(R2)
≥					MOV	R2,R0		;RET VAL BACK
≥					MOV	(SP)+,R2	;PUT R2 BACK
≥				CNSM.X:	RTS	PC		;RETURN
≥				
≥				CELLS:	BLKW	10		;A BLOCK OF 10 CELL POINTERS
≥				
≥				;This is the marking method for cells:
≥				MCELLS:	MOV	R2,-(SP)	;
≥				MCL.1:	MOV	#CELLS+20,R2	;WILL LOOP THROUGH
≥					MOV	-(R2),R0	;PICK UP POINTER
≥					JSR	PC,MARKR0	;MARK IT
≥					MOV	R0,(R2)		;PUT POINTER AWAY
≥					CMP	R0,#CELLS	;DONE YET ?
≥					BGT	MCL.1		;NOPE
≥					RTS	RF		;YES
≥				
≥				MCLNK:	MMETH	MCELLS		;SPACE FOR LINK (IMPURE CODE)
≥				
≥				;; ** next two lines go somewhere into initialization code
≥					MOV	#MCLNK,R0
≥					JSR	PC,LNKMTH
≥				;; END OF EXAMPLE
≥				
≥					⊗
≥					
≥					;MAPPTR:	;(IN CASE YOU HAD FORGOTTEN)
≠MOV≡≡R2≡≡SP≡≥	031756	010246				MOV	R2,-(SP)	;
≠MOV≡≡MMETHS≡≡R2≡≥	031760	016702	777726			MOV	MMETHS,R2	;LIST OF MARKING METHS
≠BEQ≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 37
	SMALLB PAL[HAL,HE]	PAGE 6.3 	SMALL BLOCK ALLOCATOR

≥	031764	001413				BEQ	2$		;DONE??
≤CALL≡≥					1$:	CALL	@METH(R2),<ROUT(RF)>
≠MOV≡≡RF≡≡SP≡≥	031766	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB ROUT(RF)
≠.IRP≡≥						       .IRP II,<ROUT(RF)>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡ROUT≡≡RF≡≡SP≡≥	031770	016546	000002				MOV	ROUT(RF),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	031774	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	032000	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡METH≡≡R2≡≥	032002	004772	000000			JSR	PC,@METH(R2)		;Call the routine
≠MOV≡≡NXTMTH≡≡R2≡≡R2≡≥	032006	016202	000002			MOV	NXTMTH(R2),R2	;NEXT METHOD
≠BNE≡≥	032012	001365				BNE	1$		;ITERATE
≠MOV≡≡SP≡≡R2≡≥	032014	012602			2$:	MOV	(SP)+,R2	;
≠RTS≡≡RF≡≥	032016	000205				RTS	RF		;RETURN
≥					
≥					;The appropriate marking intrinsic for spaces whose blocks contain
≥					;no pointer subfields:
≠JMP≡≡ROUT≡≡RF≡≥	032020	000175	000002		MKRTJM:	JMP	@ROUT(RF)	;
≥					
≥					MARKR0:	;This will be called by each marking method:
≠TST≡≡R0≡≥	032024	005700				TST	R0		;DON'T MARK A NULL
≠BEQ≡≥	032026	001404				BEQ	1$		;
≠JSR≡≡PC≡≡PTRSID≡≥	032030	004767	001776			JSR	PC,PTRSID	;GETS SPACE DESCRIPTOR INTO R1
≠JSR≡≡PC≡≡MAPRTN≡≡R1≡≥	032034	004771	000002			JSR	PC,@MAPRTN(R1)	;CALL APPROPRIATE MARKING INTRINSIC
≠RTS≡≡PC≡≥	032040	000207			1$:	RTS	PC
≥					
≥					; Add a method (in R0) to the "MMETHS" list:
≠MOV≡≡MMETHS≡≡NXTMTH≡≡R0≡≥	032042	016760	777644	000002	LNKMTH:	MOV	MMETHS,NXTMTH(R0)
≠MOV≡≡R0≡≡MMETHS≡≥	032050	010067	777636			MOV	R0,MMETHS
≠RTS≡≡PC≡≥	032054	000207				RTS	PC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 38
	SMALLB PAL[HAL,HE]	PAGE 7 	SMALL BLOCK ALLOCATOR

≥					; MARKPH, MKROUT
≥					
≤ROUTIN≡≥					ROUTINE MARKPH		;The marking phase of garbage collection
≠.IFNB≡≥					           .IFNB 
≥						    NNNN==0
≥						       .IRP II,<>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≥						       .IRP II,<>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≥						   .ENDC
≥					MARKPH:
≠MOV≡≡R2≡≡SP≡≥	032056	010246				MOV	R2,-(SP)	;
≠MOV≡≡R3≡≡SP≡≥	032060	010346				MOV	R3,-(SP)	;
≠MOV≡≡SIDLST≡≡R2≡≥	032062	016702	777634			MOV	SIDLST,R2	;ALL SIZES
≠BEQ≡≥	032066	001440				BEQ	5$		;DONE ALREADY??
≠TST≡≡GCFG≡≡R2≡≥	032070	005762	000010		1$:	TST	GCFG(R2)	;A GC SPACE??
≠BEQ≡≥	032074	001422				BEQ	4$		;NO, GO ON TO NEXT
≠MOV≡≡SIZE≡≡R2≡≡R3≡≥	032076	016203	000004			MOV	SIZE(R2),R3	;
≠INC≡≡R3≡≥	032102	005203				INC	R3		;ONE FOR TAG WORD
≠ASL≡≡R3≡≥	032104	006303				ASL	R3		;WORDS TO BYTES
≠MOV≡≡FSTBUF≡≡R2≡≡R1≡≥	032106	016201	000022			MOV	FSTBUF(R2),R1	;CLEAR THIS BUFFER
≠BEQ≡≥	032112	001413				BEQ	4$		;IF THERE IS ONE
≠MOV≡≡FSTBLK≡≡R1≡≡R0≡≥	032114	016100	000006		2$:	MOV	FSTBLK(R1),R0	;FIRST BLOCK
≠CLRB≡≡TAG≡≡R0≡≥	032120	105060	777777		3$:	CLRB	TAG(R0)		;CLEAR TAG
≠ADD≡≡R3≡≡R0≡≥	032124	060300				ADD	R3,R0		;BUMP POINTER TO NEXT
≠CMP≡≡R0≡≡LSTBLK≡≡R1≡≥	032126	020061	000004			CMP	R0,LSTBLK(R1)	;DONE THIS BUFFER?
≠BLE≡≥	032132	003772				BLE	3$		;If not keep going
≠MOV≡≡NXTBUF≡≡R1≡≡R1≡≥	032134	016101	000000			MOV	NXTBUF(R1),R1	;ON TO NEXT BUFFER
≠BNE≡≥	032140	001365				BNE	2$		;IF WE HAVE ONE
≠MOV≡≡NXTSID≡≡R2≡≡R2≡≥	032142	016202	000016		4$:	MOV	NXTSID(R2),R2	;GO ON TO NEXT SPACE
≠BNE≡≥	032146	001350				BNE	1$		;
≥					
≤CALL≡≥						CALL	MAPPTR,<#MKROUT> ;DO THE ACTUAL MARKING
≠MOV≡≡RF≡≡SP≡≥	032150	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB #MKROUT
≠.IRP≡≥						       .IRP II,<#MKROUT>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡MKROUT≡≡SP≡≥	032152	012746	032176				MOV	#MKROUT,-(SP);Push an argument
≡NNNN≡≡NNNN≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 39
	SMALLB PAL[HAL,HE]	PAGE 7.1 	SMALL BLOCK ALLOCATOR

≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	032156	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	032162	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡MAPPTR≡≥	032164	004767	777566			JSR	PC,MAPPTR		;Call the routine
≥						
≠MOV≡≡SP≡≡R3≡≥	032170	012603			5$:	MOV	(SP)+,R3	;RESTORE
≠MOV≡≡SP≡≡R2≡≥	032172	012602				MOV	(SP)+,R2
≠RTS≡≡RF≡≥	032174	000205				RTS	RF
≥					
≠MOVB≡≡TAG≡≡R0≡≥	032176	112760	000377	777777	MKROUT:	MOVB	#377,TAG(R0)	;
≠RTS≡≡PC≡≥	032204	000207				RTS	PC		;
≥					
≤ROUTIN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 40
	SMALLB PAL[HAL,HE]	PAGE 8 	SMALL BLOCK ALLOCATOR

≥					ROUTINE CMPSP,<SPC>
≠.IFNB≡≥					           .IFNB SPC
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<SPC>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<SPC>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡SPC≡≥					                  .IFDF SPC
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for SPC
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡SPC≠≥		000002			                   SPC == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					CMPSP:
≥					
≥					; Performs all data moving required to compact one size space
≥					
≠MOV≡≡R2≡≡SP≡≥	032206	010246				MOV	R2,-(SP)	;SAVE SOME ACS
≠MOV≡≡R3≡≡SP≡≥	032210	010346				MOV	R3,-(SP)	;
≠MOV≡≡R4≡≡SP≡≥	032212	010446				MOV	R4,-(SP)	;
≠MOV≡≡SPC≡≡RF≡≡R2≡≥	032214	016502	000002			MOV	SPC(RF),R2	;SPACE DSCR
≠MOV≡≡FSTBUF≡≡R2≡≡R3≡≥	032220	016203	000022			MOV	FSTBUF(R2),R3	;OLDEST
≠MOV≡≡LSTBUF≡≡R2≡≡R4≡≥	032224	016204	000024			MOV	LSTBUF(R2),R4	;NEWEST
≠CMP≡≡R3≡≡R4≡≥	032230	020304				CMP	R3,R4		;See if there's at least two buffers
≠BEQ≡≥	032232	001435				BEQ	3$		;If not punt
≠JSR≡≡PC≡≥	032234	004767	000076			JSR	PC,10$		;First FREE INTO R1
≥									;MAY MODIFY R3
≠BEQ≡≥	032240	001432				BEQ	3$		;NO FREE
≠JSR≡≡PC≡≥	032242	004767	000142			JSR	PC,20$		;GET A RECORD TO MOVE (last used)
≥									;INTO R0 (MAY MODIFY R4)
≠BEQ≡≥	032246	001427				BEQ	3$		;
≠MOV≡≡R1≡≡SP≡≥	032250	010146			1$:	MOV	R1,-(SP)	;SAVE THESE
≠MOV≡≡R0≡≡SP≡≥	032252	010046				MOV	R0,-(SP)	;
≠MOVB≡≡TAG≡≡R1≡≥	032254	112761	000377	777777		MOVB	#377,TAG(R1)	;Old free now being used
≠CLRB≡≡TAG≡≡R0≡≥	032262	105060	777777			CLRB	TAG(R0)		;Old used now free
≠MOV≡≡SIZE≡≡R2≡≡R2≡≥	032266	016202	000004			MOV	SIZE(R2),R2	;
≠MOV≡≡R0≡≡R1≡≥	032272	012021			2$:	MOV	(R0)+,(R1)+	;COPY RECORD
≠SOB≡≡R2≡≥	032274	077202				SOB	R2, 2$		;COUNT DOWN TIL DONE
≠MOV≡≡SPC≡≡RF≡≡R2≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 41
	SMALLB PAL[HAL,HE]	PAGE 8.1 	SMALL BLOCK ALLOCATOR

≥	032276	016502	000002			MOV	SPC(RF),R2	;YES
≠MOV≡≡SP≡≡R0≡≥	032302	012600				MOV	(SP)+,R0	;GET ACS BACK
≠MOV≡≡SP≡≡R1≡≥	032304	012601				MOV	(SP)+,R1	;
≠MOV≡≡R1≡≡WORD0≡≡R0≡≥	032306	010160	000000			MOV	R1,WORD0(R0)	;POINT AT THIS ONE
≠JSR≡≡PC≡≥	032312	004767	000032			JSR	PC,12$		;NEXT FREE
≠BEQ≡≥	032316	001403				BEQ	3$
≠JSR≡≡PC≡≥	032320	004767	000076			JSR	PC,22$		;NEXT RECORD
≠BNE≡≥	032324	001351				BNE	1$		;PROCESS THAT ONE
≥					3$:
≠MOV≡≡SP≡≡R4≡≥	032326	012604				MOV	(SP)+,R4	;
≠MOV≡≡SP≡≡R3≡≥	032330	012603				MOV	(SP)+,R3	;
≠MOV≡≡SP≡≡R2≡≥	032332	012602				MOV	(SP)+,R2
≠RTS≡≡RF≡≥	032334	000205				RTS	RF
≥					
≠MOV≡≡FSTBLK≡≡R3≡≡R1≡≥	032336	016301	000006		10$:	MOV	FSTBLK(R3),R1	;FIND A FREE BLOCK
≠TSTB≡≡TAG≡≡R1≡≥	032342	105761	777777		11$:	TSTB	TAG(R1)		;FREE
≠BEQ≡≥	032346	001416				BEQ	14$		;YES
≠ADD≡≡SIZE≡≡R2≡≡R1≡≥	032350	066201	000004		12$:	ADD	SIZE(R2),R1	;LOOK AT NEXT
≠ADD≡≡SIZE≡≡R2≡≡R1≡≥	032354	066201	000004			ADD	SIZE(R2),R1	;ADD TWICE SINCE WANT TRUE ADDRESS
≠TST≡≡R1≡≥	032360	005721				TST	(R1)+		;ADD IN TAG WORD OFFSET
≠CMP≡≡R1≡≡LSTBLK≡≡R3≡≥	032362	020163	000004			CMP	R1,LSTBLK(R3)	;MORE TO TRY??
≠BLE≡≥	032366	003765				BLE	11$		;TRY AGAIN
≠MOV≡≡NXTBUF≡≡R3≡≡R3≡≥	032370	016303	000000			MOV	NXTBUF(R3),R3	;NEXT NEWEST BUFFER
≠BEQ≡≥	032374	001402				BEQ	13$		;LOOK THERE
≠CMP≡≡R3≡≡R4≡≥	032376	020304				CMP	R3,R4		;IF NOT TO THE used record SUPPLIER
≠BNE≡≥	032400	001356				BNE	10$
≠CLR≡≡R1≡≥	032402	005001			13$:	CLR	R1
≠TST≡≡R1≡≥	032404	005701			14$:	TST	R1		;GET FLAGS CORRECT
≠RTS≡≡PC≡≥	032406	000207				RTS	PC
≥					
≥					
≠MOV≡≡LSTBLK≡≡R4≡≡R0≡≥	032410	016400	000004		20$:	MOV	LSTBLK(R4),R0	;FIND A FULL BLOCK
≠TSTB≡≡TAG≡≡R0≡≥	032414	105760	777777		21$:	TSTB	TAG(R0)		;FULL
≠BNE≡≥	032420	001016				BNE	24$		;YES
≠SUB≡≡SIZE≡≡R2≡≡R0≡≥	032422	166200	000004		22$:	SUB	SIZE(R2),R0	;LOOK AT NEXT
≠SUB≡≡SIZE≡≡R2≡≡R0≡≥	032426	166200	000004			SUB	SIZE(R2),R0	;Subtrct TWICE SINCE WANT TRUE ADDRESS
≠TST≡≡R0≡≥	032432	005740				TST	-(R0)		;Subtract TAG WORD OFFSET
≠CMP≡≡R0≡≡FSTBLK≡≡R4≡≥	032434	020064	000006			CMP	R0,FSTBLK(R4)	;MORE TO TRY??
≠BGE≡≥	032440	002365				BGE	21$		;TRY AGAIN
≠MOV≡≡PRVBUF≡≡R4≡≡R4≡≥	032442	016404	000002			MOV	PRVBUF(R4),R4	;NEXT NEWEST BUFFER
≠BEQ≡≥	032446	001402				BEQ	23$		;LOOK THERE
≠CMP≡≡R3≡≡R4≡≥	032450	020304				CMP	R3,R4		;IF NOT TO THE FREE SUPPLIER
≠BNE≡≥	032452	001356				BNE	20$
≠CLR≡≡R0≡≥	032454	005000			23$:	CLR	R0
≠RTS≡≡PC≡≥	032456	000207			24$:	RTS	PC
≤ROUTIN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 42
	SMALLB PAL[HAL,HE]	PAGE 9 	SMALL BLOCK ALLOCATOR

≥					ROUTINE COMPACT
≠.IFNB≡≥					           .IFNB 
≥						    NNNN==0
≥						       .IRP II,<>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≥						       .IRP II,<>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≥						   .ENDC
≥					COMPACT:
≠MOV≡≡R2≡≡SP≡≥	032460	010246				MOV	R2,-(SP)	
≠MOV≡≡SIDLST≡≡R2≡≥	032462	016702	777234			MOV	SIDLST,R2	;LIST OF ALL SIZES
≠BEQ≡≥	032466	001415				BEQ	3$		;NULL LIST??
≠TST≡≡GCFG≡≡R2≡≥	032470	005762	000010		1$:	TST	GCFG(R2)	;COLLECTABLE??
≠BEQ≡≥	032474	001407				BEQ	2$		;BR IF NOT
≤CALL≡≥						CALL	CMPSP,<R2>	;COMPACT THIS SPACE
≠MOV≡≡RF≡≡SP≡≥	032476	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R2
≠.IRP≡≥						       .IRP II,<R2>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R2≡≡SP≡≥	032500	010246					MOV	R2,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	032502	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	032506	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡CMPSP≡≥	032510	004767	777472			JSR	PC,CMPSP		;Call the routine
≠MOV≡≡NXTSID≡≡R2≡≡R2≡≥	032514	016202	000016		2$:	MOV	NXTSID(R2),R2
≠BNE≡≥	032520	001363				BNE	1$
≤CALL≡≥					3$:	CALL	MAPPTR,<#MUNLNK> ;MUNCH ALL LINKS
≠MOV≡≡RF≡≡SP≡≥	032522	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB #MUNLNK
≠.IRP≡≥						       .IRP II,<#MUNLNK>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡MUNLNK≡≡SP≡≥	032524	012746	032546				MOV	#MUNLNK,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 43
	SMALLB PAL[HAL,HE]	PAGE 9.1 	SMALL BLOCK ALLOCATOR

≥	032530	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	032534	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡MAPPTR≡≥	032536	004767	777214			JSR	PC,MAPPTR		;Call the routine
≠MOV≡≡SP≡≡R2≡≥	032542	012602			4$:	MOV	(SP)+,R2	;RETURN
≠RTS≡≡RF≡≥	032544	000205				RTS	RF
≥					
≥					;When MUNLNK is called, R0 is a pointer to a block which may or may not have
≥					;been moved by CPFY.  If it has been moved, then TAG(R0) will have
≥					;been set to 0, and WORD0(R0) will point at the correct block.
≥					;The routine will always return a pointer to the "real" block,
≥					;so MARKR0 will return a correct value.
≥					
≠TSTB≡≡TAG≡≡R0≡≥	032546	105760	777777		MUNLNK:	TSTB	TAG(R0)		;DID WE MOVE IT ??
≠BNE≡≥	032552	001002				BNE	1$		;
≠MOV≡≡WORD0≡≡R0≡≡R0≡≥	032554	016000	000000			MOV	WORD0(R0),R0	;YES, PUT NEW POINTER IN PLACE
≠RTS≡≡PC≡≥	032560	000207			1$:	RTS	PC		;
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 44
	SMALLB PAL[HAL,HE]	PAGE 10 	SMALL BLOCK ALLOCATOR

≥					; SWEEP
≥					
≤ROUTIN≡≥					ROUTINE SWEEP		;The sweep phase of garbage collection
≠.IFNB≡≥					           .IFNB 
≥						    NNNN==0
≥						       .IRP II,<>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≥						       .IRP II,<>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≥						   .ENDC
≥					SWEEP:
≠MOV≡≡R2≡≡SP≡≥	032562	010246				MOV	R2,-(SP)	;
≠MOV≡≡SIDLST≡≡R2≡≥	032564	016702	777132			MOV	SIDLST,R2	;LIST OF SIZES
≠BEQ≡≥	032570	001405				BEQ	2$
≠JSR≡≡PC≡≡SWP.≡≥	032572	004767	000030		1$:	JSR	PC,SWP.		;GO SWEEP ONE AREA
≠MOV≡≡NXTSID≡≡R2≡≡R2≡≥	032576	016202	000016			MOV	NXTSID(R2),R2	;ITERATE
≠BNE≡≥	032602	001373				BNE	1$		;
≠MOV≡≡SP≡≡R2≡≥	032604	012602			2$:	MOV	(SP)+,R2	;
≠RTS≡≡RF≡≥	032606	000205				RTS	RF		;
≥					
≤ROUTIN≡≥					ROUTINE SWEEP1,<SPCC>	
≠.IFNB≡≥					           .IFNB SPCC
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<SPCC>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<SPCC>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡SPCC≡≥					                  .IFDF SPCC
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for SPCC
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡SPCC≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 45
	SMALLB PAL[HAL,HE]	PAGE 10.1 	SMALL BLOCK ALLOCATOR

≥		000002			                   SPCC == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					SWEEP1:
≠MOV≡≡R2≡≡SP≡≥	032610	010246				MOV	R2,-(SP)	;SAVE REGISTERS
≠MOV≡≡SPCC≡≡RF≡≡R2≡≥	032612	016502	000002			MOV	SPCC(RF),R2	;GET A SPACE
≠JSR≡≡PC≡≡SWP.≡≥	032616	004767	000004			JSR	PC,SWP.		;SWEEP ONE AREA
≠MOV≡≡SP≡≡R2≡≥	032622	012602				MOV	(SP)+,R2	
≠RTS≡≡RF≡≥	032624	000205				RTS	RF
≥					
≥					SWP.:	;R2 = LOC[Space descriptor]
≠TST≡≡GCFG≡≡R2≡≥	032626	005762	000010			TST	GCFG(R2)	;IS THIS SPACE FOR SWEEPING??
≠BNE≡≥	032632	001001				BNE	1$		;
≠RTS≡≡PC≡≥	032634	000207				RTS	PC		;NO
≠MOV≡≡R3≡≡SP≡≥	032636	010346			1$:	MOV	R3,-(SP)	;YES
≠MOV≡≡R4≡≡SP≡≥	032640	010446				MOV	R4,-(SP)	;
≠CLR≡≡FFREE≡≡R2≡≥	032642	005062	000020			CLR	FFREE(R2)	;WILL BUILD A REAL FREE LIST
≠CLR≡≡NFREE≡≡R2≡≥	032646	005062	000030			CLR	NFREE(R2)	;SINCE WE WILL FIX COUNTS
≠CLR≡≡NALLOC≡≡R2≡≥	032652	005062	000026			CLR	NALLOC(R2)	;
≠MOV≡≡LSTBUF≡≡R2≡≡R3≡≥	032656	016203	000024			MOV	LSTBUF(R2),R3	;OLDEST BUFFER
≠BEQ≡≥	032662	001503				BEQ	6$		;IF ANY
≠MOV≡≡SIZE≡≡R2≡≡R4≡≥	032664	016204	000004			MOV	SIZE(R2),R4	;COMPUTE SIZE
≠INC≡≡R4≡≥	032670	005204				INC	R4		;IN BYTES OF WHOLE THING
≠ASL≡≡R4≡≥	032672	006304				ASL	R4		;
≠MOV≡≡LSTBLK≡≡R3≡≡R0≡≥	032674	016300	000004		2$:	MOV	LSTBLK(R3),R0	;GET A BLK
≠TSTB≡≡TAG≡≡R0≡≥	032700	105760	777777		3$:	TSTB	TAG(R0)		;ALLOCATED?
≠BEQ≡≥	032704	001403				BEQ	4$		;NO
≠INC≡≡NALLOC≡≡R2≡≥	032706	005262	000026			INC	NALLOC(R2)	;YES
≠BR≡≥	032712	000407				BR	5$
≠INC≡≡NFREE≡≡R2≡≥	032714	005262	000030		4$:	INC	NFREE(R2)	;LINK UP A FREE
≠MOV≡≡FFREE≡≡R2≡≡WORD0≡≡R0≡≥	032720	016260	000020	000000		MOV	FFREE(R2),WORD0(R0)
≠MOV≡≡R0≡≡FFREE≡≡R2≡≥	032726	010062	000020			MOV	R0,FFREE(R2)
≠SUB≡≡R4≡≡R0≡≥	032732	160400			5$:	SUB	R4,R0		;BUMP POINTER TO NEXT IN BUFFER
≠CMP≡≡R0≡≡FSTBLK≡≡R3≡≥	032734	020063	000006			CMP	R0,FSTBLK(R3)	;DONE BUFFER??
≠BGE≡≥	032740	002357				BGE	3$		;NO
≠MOV≡≡PRVBUF≡≡R3≡≡R3≡≥	032742	016303	000002			MOV	PRVBUF(R3),R3	;YES GO BACK TO NEXT
≠BNE≡≥	032746	001352				BNE	2$		;IF THERE IS ONE
≥					
≠TST≡≡CMPOK≡≥	032750	005767	776744			TST	CMPOK		;If we're not compacting then can't
≠BNE≡≥	032754	001046				BNE	6$		;  release any buffers
≥					
≥					;Here's where we release any extra buffers freed by compacting
≥					
≠MOV≡≡NFREE≡≡R2≡≡R0≡≥	032756	016200	000030		10$:	MOV	NFREE(R2),R0
≠SUB≡≡NPERB≡≡R2≡≡R0≡≥	032762	166200	000006			SUB	NPERB(R2),R0	;Number free left after releasing a buffer
≠CMP≡≡R0≡≡NMIN≡≡R2≡≥	032766	020062	000012			CMP	R0,NMIN(R2)	;Check that there are still enough left
≠BLT≡≥	032772	002437				BLT	6$		;Nope - 
≠MOV≡≡R0≡≡R1≡≥	032774	010001				MOV	R0,R1
≠ADD≡≡NALLOC≡≡R2≡≡R1≡≥	032776	066201	000026			ADD	NALLOC(R2),R1	;Now check that the percentage free is ok
≠MUL≡≡NPCT≡≡R2≡≡R1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 46
	SMALLB PAL[HAL,HE]	PAGE 10.2 	SMALL BLOCK ALLOCATOR

≥	033002	070162	000014			MUL	NPCT(R2),R1
≠DIV≡≡R1≡≥	033006	071127	000144			DIV	#144,R1		; NPCT*(NFREE+NALLOC)/100
≠CMP≡≡R0≡≡R1≡≥	033012	020001				CMP	R0,R1		;Well?
≠BLT≡≥	033014	002426				BLT	6$		;Nope -
≠MOV≡≡R0≡≡NFREE≡≡R2≡≥	033016	010062	000030			MOV	R0,NFREE(R2)	;Yup - release the buffer. New free count
≠MOV≡≡FFREE≡≡R2≡≡R1≡≥	033022	016201	000020			MOV	FFREE(R2),R1	;Now fix up the free list
≠DEC≡≡R0≡≥	033026	005300				DEC	R0
≠BEQ≡≥	033030	001403				BEQ	12$
≠MOV≡≡WORD0≡≡R1≡≡R1≡≥	033032	016101	000000		11$:	MOV	WORD0(R1),R1	;Run down free list
≠SOB≡≡R0≡≥	033036	077003				SOB	R0,11$		;Till new end
≠CLR≡≡WORD0≡≡R1≡≥	033040	005061	000000		12$:	CLR	WORD0(R1)	;New end of list
≠MOV≡≡LSTBUF≡≡R2≡≡R0≡≥	033044	016200	000024			MOV	LSTBUF(R2),R0	;Last buffer - the one we'll free
≠MOV≡≡PRVBUF≡≡R0≡≡R1≡≥	033050	016001	000002			MOV	PRVBUF(R0),R1	;New last buffer
≠MOV≡≡R1≡≡LSTBUF≡≡R2≡≥	033054	010162	000024			MOV	R1,LSTBUF(R2)	;Remove freed buffer from chain
≠CLR≡≡NXTBUF≡≡R1≡≥	033060	005061	000000			CLR	NXTBUF(R1)
≠JSR≡≡PC≡≡RLFREE≡≥	033064	004767	775520			JSR	PC,RLFREE	;Release the buffer
≠BR≡≥	033070	000732				BR	10$		;Free as many as you can
≥					
≠CMP≡≡NFREE≡≡R2≡≡NMIN≡≡R2≡≥	033072	026262	000030	000012	6$:	CMP	NFREE(R2),NMIN(R2)	;NEED MORE??
≠BGT≡≥	033100	003010				BGT	8$		;AT LEAST HAVE MIN NUMBER
≤CALL≡≥					7$:	CALL	ADDBUF,<R2>	;NO, ADD A BUFFER FULL
≠MOV≡≡RF≡≡SP≡≥	033102	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R2
≠.IRP≡≥						       .IRP II,<R2>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R2≡≡SP≡≥	033104	010246					MOV	R2,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	033106	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	033112	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡ADDBUF≡≥	033114	004767	001336			JSR	PC,ADDBUF		;Call the routine
≠BR≡≥	033120	000764				BR	6$		;AND TRY AGAIN
≠MOV≡≡NFREE≡≡R2≡≡R0≡≥	033122	016200	000030		8$:	MOV	NFREE(R2),R0	;SEE IF HIGH ENOUGH PERCENTAGE
≠ADD≡≡NALLOC≡≡R2≡≡R0≡≥	033126	066200	000026			ADD	NALLOC(R2),R0	;OF FREES
≠MUL≡≡NPCT≡≡R2≡≡R0≡≥	033132	070062	000014			MUL	NPCT(R2),R0	; 
≠DIV≡≡R0≡≥	033136	071027	000144			DIV	#144,R0		; NPCT*(NFREE+NALLOC)/=100
≠CMP≡≡NFREE≡≡R2≡≡R0≡≥	033142	026200	000030			CMP	NFREE(R2),R0	;
≠BGT≡≥	033146	003010				BGT	9$		;IF DONT HAVE ENOUGH
≤CALL≡≥						CALL	ADDBUF,<R2>	;GET A BUFFER LOAD
≠MOV≡≡RF≡≡SP≡≥	033150	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R2
≠.IRP≡≥						       .IRP II,<R2>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R2≡≡SP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 47
	SMALLB PAL[HAL,HE]	PAGE 10.3 	SMALL BLOCK ALLOCATOR

≥	033152	010246					MOV	R2,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	033154	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	033160	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡ADDBUF≡≥	033162	004767	001270			JSR	PC,ADDBUF		;Call the routine
≠BR≡≥	033166	000755				BR	8$		;AND TRY AGAIN
≠MOV≡≡SP≡≡R4≡≥	033170	012604			9$:	MOV	(SP)+,R4	;RESTORE
≠MOV≡≡SP≡≡R3≡≥	033172	012603				MOV	(SP)+,R3
≠RTS≡≡PC≡≥	033174	000207				RTS	PC
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 48
	SMALLB PAL[HAL,HE]	PAGE 11 	SMALL BLOCK ALLOCATOR

≥					; GC, NOGC, YESGC, NOCMP, YESCMP
≥					
≤ROUTIN≡≥					ROUTINE GC
≠.IFNB≡≥					           .IFNB 
≥						    NNNN==0
≥						       .IRP II,<>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≥						       .IRP II,<>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≥						   .ENDC
≥					GC:
≠INC≡≡GCDONE≡≥	033176	005267	776514			INC	GCDONE		;Keep track of how many times we GC
≤CALL≡≥						CALL	MARKPH		;MARK EVERYONE
≠MOV≡≡RF≡≡SP≡≥	033202	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB 
≥						       .IRP II,<>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	033204	012746	006400			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	033210	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡MARKPH≡≥	033212	004767	776640			JSR	PC,MARKPH		;Call the routine
≠TST≡≡CMPOK≡≥	033216	005767	776476			TST	CMPOK		;IF DONT WANT COMPACTING
≠BNE≡≥	033222	001006				BNE	1$		;THEN DONT DO IT
≤CALL≡≥						CALL	COMPACT		;COMPACT
≠MOV≡≡RF≡≡SP≡≥	033224	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB 
≥						       .IRP II,<>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	033226	012746	006400			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	033232	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡COMPAC≡≥	033234	004767	777220			JSR	PC,COMPACT		;Call the routine
≤CALL≡≥					1$:	CALL	SWEEP		;SWEEP UP LOOSE GARBAGE
≠MOV≡≡RF≡≡SP≡≥	033240	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 49
	SMALLB PAL[HAL,HE]	PAGE 11.1 	SMALL BLOCK ALLOCATOR

≥						   .IFNB 
≥						       .IRP II,<>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	033242	012746	006400			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	033246	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡SWEEP≡≥	033250	004767	777306			JSR	PC,SWEEP		;Call the routine
≠RTS≡≡RF≡≥	033254	000205				RTS	RF
≥					
≥					NOGC:
≠COMMEN≡≥				COMMENT ⊗ Called by anyone who has entered that stage of code
≥					during which he does not want garbage collect to happen.  ⊗
≤EVWAIT≡≥						EVWAIT	SBEVT		;Grab exclusion
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	033256	016746	776426			      MOV SBEVT,-(SP)
≥	033262	104010				104010
≠INC≡≡GCOK≡≥	033264	005267	776424			INC	GCOK		;Increment the count of those who say nay
≤EVSIG≡≥						EVSIG	SBEVT		;Release exclusion
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	033270	016746	776414			      MOV SBEVT,-(SP)
≥	033274	104012				104012
≠RTS≡≡PC≡≥	033276	000207				RTS	PC		;Done
≥					
≥					YESGC:
≠COMMEN≡≥				COMMENT ⊗ Called by anyone who has exited that stage of code
≥					during which he does not want garbage collect to happen.  ⊗
≥					
≤EVWAIT≡≥						EVWAIT	SBEVT		;Grab exclusion
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	033300	016746	776404			      MOV SBEVT,-(SP)
≥	033304	104010				104010
≠DEC≡≡GCOK≡≥	033306	005367	776402			DEC	GCOK		;Remove the effect we did in NOGC.
≤EVSIG≡≥						EVSIG	SBEVT		;Release exclusion
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	033312	016746	776372			      MOV SBEVT,-(SP)
≥	033316	104012				104012
≠BGT≡≥	033320	003004				BGT	1$		;Reasonable?
≤HALERR≡≥						HALERR	2$		;No
≠MOV≡≡SP≡≥	033322	012746	033334			MOV #2$,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	033326	004777	760460			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠RTS≡≡PC≡≥	033332	000207			1$:	RTS	PC		;Yes.
≤ASCIE≡≥					2$:	ASCIE	</GCOK IS NEGATIVE/>
≠.ASCIZ≡≥	033334	   107		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 50
	SMALLB PAL[HAL,HE]	PAGE 11.2 	SMALL BLOCK ALLOCATOR

≥	033335	   103		
≥	033336	   117		
≥	033337	   113		
≥	033340	   040		
≥	033341	   111		
≥	033342	   123		
≥	033343	   040		
≥	033344	   116		
≥	033345	   105		
≥	033346	   107		
≥	033347	   101		
≥	033350	   124		
≥	033351	   111		
≥	033352	   126		
≥	033353	   105		
≥	033354	   000		
≥					       .ASCIZ /GCOK IS NEGATIVE/
≠.EVEN≡≥		033356			       .EVEN
≥					
≥					NOCMP:
≠COMMEN≡≥				COMMENT ⊗ Called by anyone who has entered that stage of code
≥					during which he does not want compacting to happen.  ⊗
≤EVWAIT≡≥						EVWAIT	SBEVT		;Grab exclusion
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	033356	016746	776326			      MOV SBEVT,-(SP)
≥	033362	104010				104010
≠INC≡≡CMPOK≡≥	033364	005267	776330			INC	CMPOK		;Increment the count of those who say nay
≤EVSIG≡≥						EVSIG	SBEVT		;Release exclusion
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	033370	016746	776314			      MOV SBEVT,-(SP)
≥	033374	104012				104012
≠RTS≡≡PC≡≥	033376	000207				RTS	PC		;Done
≥					
≥					YESCMP:
≠COMMEN≡≥				COMMENT ⊗ Called by anyone who has exited that stage of code
≥					during which he does not want compacting to happen.  ⊗
≥					
≤EVWAIT≡≥						EVWAIT	SBEVT		;Grab exclusion
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	033400	016746	776304			      MOV SBEVT,-(SP)
≥	033404	104010				104010
≠DEC≡≡CMPOK≡≥	033406	005367	776306			DEC	CMPOK		;Remove the effect we did in NOGC.
≤EVSIG≡≥						EVSIG	SBEVT		;Release exclusion
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	033412	016746	776272			      MOV SBEVT,-(SP)
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 51
	SMALLB PAL[HAL,HE]	PAGE 11.3 	SMALL BLOCK ALLOCATOR

≥	033416	104012				104012
≠BGT≡≥	033420	003004				BGT	1$		;Reasonable?
≤HALERR≡≥						HALERR	2$		;No
≠MOV≡≡SP≡≥	033422	012746	033434			MOV #2$,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	033426	004777	760360			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠RTS≡≡PC≡≥	033432	000207			1$:	RTS	PC		;Yes.
≤ASCIE≡≥					2$:	ASCIE	</CMPOK IS NEGATIVE/>
≠.ASCIZ≡≥	033434	   103		
≥	033435	   115		
≥	033436	   120		
≥	033437	   117		
≥	033440	   113		
≥	033441	   040		
≥	033442	   111		
≥	033443	   123		
≥	033444	   040		
≥	033445	   116		
≥	033446	   105		
≥	033447	   107		
≥	033450	   101		
≥	033451	   124		
≥	033452	   111		
≥	033453	   126		
≥	033454	   105		
≥	033455	   000		
≥					       .ASCIZ /CMPOK IS NEGATIVE/
≠.EVEN≡≥		033456			       .EVEN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 52
	SMALLB PAL[HAL,HE]	PAGE 12 	SMALL BLOCK ALLOCATOR

≥					; GETSBK, GETBLK, GETSID, PTRSID
≥					
≥					GETSBK:	
≥					;
≥					;	MOV	[SPACE DESCRIPTOR],R0
≥					;	JSR	PC,GETSBK
≥					;	<RETURNS WITH A BLOCK IN R0>
≥					;
≠MOV≡≡R0≡≡R1≡≥	033456	010001				MOV	R0,R1			
≤EVWAIT≡≥					GETBL:	EVWAIT	SBEVT			;CRITICAL REGION STARTS
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	033460	016746	776224			      MOV SBEVT,-(SP)
≥	033464	104010				104010
≠TST≡≡R1≡≥	033466	005701			1$:	TST	R1			;
≠BEQ≡≡GETBER≡≥	033470	001475				BEQ	GETBER			;CONSISTENCY CHECK
≠MOV≡≡FFREE≡≡R1≡≡R0≡≥	033472	016100	000020			MOV	FFREE(R1),R0		;R0 ← FIRST FREE BLOCK
≠BNE≡≥	033476	001046				BNE	5$			;DID WE GET ONE
≠MOV≡≡R1≡≡SP≡≥	033500	010146				MOV	R1,-(SP)		;NO,
≠TST≡≡GCFG≡≡R1≡≥	033502	005761	000010			TST	GCFG(R1)		;IS GC OK FOR THIS AREA?
≠BEQ≡≥	033506	001422				BEQ	2$			;NO, MUST ADD
≠TST≡≡GCOK≡≥	033510	005767	776200			TST	GCOK			;IS GARBAGE COLLECTION OK AT ALL
≠BNE≡≥	033514	001017				BNE	2$			;no.
≥						; Must be able to get GNEVT and INTEVT.  Don't need them right now, though.
≤EVTST≡≥						EVTST	GNEVT			;We must have this available.
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	033516	016746	024456			      MOV GNEVT,-(SP)
≥	033522	104022				104022
≠BCS≡≥	033524	103413				BCS	2$			;
≤EVSIG≡≥						EVSIG	GNEVT			;
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	033526	016746	024446			      MOV GNEVT,-(SP)
≥	033532	104012				104012
≤EVTST≡≥						EVTST	INTEVT			;We must have this available.
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	033534	016746	001550			      MOV INTEVT,-(SP)
≥	033540	104022				104022
≠BCS≡≥	033542	103404				BCS	2$			;
≤EVSIG≡≥						EVSIG	INTEVT			;
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	033544	016746	001540			      MOV INTEVT,-(SP)
≥	033550	104012				104012
≠BR≡≥	033552	000410				BR 	3$			;
≤CALL≡≥					2$:	CALL	ADDBUF,<R1>		;NO, JUST GET A BUFFER
≠MOV≡≡RF≡≡SP≡≥	033554	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 53
	SMALLB PAL[HAL,HE]	PAGE 12.1 	SMALL BLOCK ALLOCATOR

≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R1
≠.IRP≡≥						       .IRP II,<R1>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R1≡≡SP≡≥	033556	010146					MOV	R1,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	033560	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	033564	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡ADDBUF≡≥	033566	004767	000664			JSR	PC,ADDBUF		;Call the routine
≠BR≡≥	033572	000406				BR 	4$			;
≤CALL≡≥					3$:	CALL	GC			;YES, GC
≠MOV≡≡RF≡≡SP≡≥	033574	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB 
≥						       .IRP II,<>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	033576	012746	006400			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	033602	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡GC≡≥	033604	004767	777366			JSR	PC,GC		;Call the routine
≠MOV≡≡SP≡≡R1≡≥	033610	012601			4$:	MOV	(SP)+,R1		;
≠BR≡≥	033612	000725				BR	1$
≠MOV≡≡WORD0≡≡R0≡≡FFREE≡≡R1≡≥	033614	016061	000000	000020	5$:	MOV	WORD0(R0),FFREE(R1)	;NEW FIRST FREE BLOCK
≠INC≡≡NALLOC≡≡R1≡≥	033622	005261	000026			INC	NALLOC(R1)		;ADJUST COUNTS
≠DEC≡≡NFREE≡≡R1≡≥	033626	005361	000030			DEC	NFREE(R1)
≠MOVB≡≡IDFLAG≡≡R1≡≡TAGID≡≡R0≡≥	033632	116160	000000	777776		MOVB	IDFLAG(R1),TAGID(R0)	;REMEMBER WHAT IT IS
≠MOV≡≡R0≡≡SP≡≥	033640	010046				MOV	R0,-(SP)		;SAVE POINTER TO BLOCK
≠MOV≡≡SIZE≡≡R1≡≡R1≡≥	033642	016101	000004			MOV	SIZE(R1),R1		;WORD COUNT
≠CLR≡≡R0≡≥	033646	005020			6$:	CLR	(R0)+			;CLEAR A WORD
≠SOB≡≡R1≡≥	033650	077102				SOB	R1,6$			;UNTIL DONE
≠MOV≡≡SP≡≡R0≡≥	033652	012600				MOV	(SP)+,R0		;RETURN VALUE BACK
≥					;Used to end critical section here. Now done by caller	ARG 11/76
≥					;	EVSIG	SBEVT			;END OF CRITICAL SECTION
≠RTS≡≡PC≡≥	033654	000207				RTS	PC
≥					
≥					;
≥					;	MOV	#ID,R0
≥					;	JSR	PC,GETBLK
≥					;
≠JSR≡≡PC≡≡GETSID≡≥	033656	004767	000104		GETBLK:	JSR	PC,GETSID		;SET UP SPC DSCR IN R1
≠BR≡≡GETBL≡≥	033662	000676				BR	GETBL
≥					
≤HALERR≡≥					GETBER:	HALERR	GERMSG
≠MOV≡≡GERMSG≡≡SP≡≥	033664	012746	033700			MOV #GERMSG,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 54
	SMALLB PAL[HAL,HE]	PAGE 12.2 	SMALL BLOCK ALLOCATOR

≥	033670	004777	760116			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠CLR≡≡R0≡≥	033674	005000				CLR	R0
≠RTS≡≡PC≡≥	033676	000207				RTS	PC
≥					
≤ASCIE≡≥					GERMSG:	ASCIE	/ATTEMPT TO ALLOCATE RECORD WITHOUT GIVING DESCRIPTOR/
≠.ASCIZ≡≥	033700	   101		
≥	033701	   124		
≥	033702	   124		
≥	033703	   105		
≥	033704	   115		
≥	033705	   120		
≥	033706	   124		
≥	033707	   040		
≥	033710	   124		
≥	033711	   117		
≥	033712	   040		
≥	033713	   101		
≥	033714	   114		
≥	033715	   114		
≥	033716	   117		
≥	033717	   103		
≥	033720	   101		
≥	033721	   124		
≥	033722	   105		
≥	033723	   040		
≥	033724	   122		
≥	033725	   105		
≥	033726	   103		
≥	033727	   117		
≥	033730	   122		
≥	033731	   104		
≥	033732	   040		
≥	033733	   127		
≥	033734	   111		
≥	033735	   124		
≥	033736	   110		
≥	033737	   117		
≥	033740	   125		
≥	033741	   124		
≥	033742	   040		
≥	033743	   107		
≥	033744	   111		
≥	033745	   126		
≥	033746	   111		
≥	033747	   116		
≥	033750	   107		
≥	033751	   040		
≥	033752	   104		
≥	033753	   105		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 55
	SMALLB PAL[HAL,HE]	PAGE 12.3 	SMALL BLOCK ALLOCATOR

≥	033754	   123		
≥	033755	   103		
≥	033756	   122		
≥	033757	   111		
≥	033760	   120		
≥	033761	   124		
≥	033762	   117		
≥	033763	   122		
≥	033764	   000		
≥					       .ASCIZ /ATTEMPT TO ALLOCATE RECORD WITHOUT GIVING DESCRIPTOR/
≠.EVEN≡≥		033766			       .EVEN
≥					
≥					GETSID:
≥					;  Given the TAGID of a space in R0, returns LOC[space descriptor] in R1.
≠MOV≡≡R0≡≡R1≡≥	033766	010001				MOV	R0,R1
≠CMP≡≡R0≡≡MAXIDF≡≥	033770	020027	000030			CMP	R0,#MAXIDF		;IN THE TABLE?
≠BGT≡≥	033774	003004				BGT	2$			;NO
≠ASL≡≡R1≡≥	033776	006301				ASL	R1
≠MOV≡≡SIDTBL≡≡R1≡≡R1≡≥	034000	016101	031724			MOV	SIDTBL(R1),R1		;YES
≠RTS≡≡PC≡≥	034004	000207			1$:	RTS	PC			;
≠MOV≡≡SIDLST≡≡R1≡≥	034006	016701	775710		2$:	MOV	SIDLST,R1		;SEARCH CHAIN
≠BEQ≡≥	034012	001774				BEQ	1$
≠CMP≡≡R0≡≡IDFLAG≡≡R1≡≥	034014	020061	000000		3$:	CMP	R0,IDFLAG(R1)		;THIS ONE??
≠BNE≡≥	034020	001371				BNE	1$			;YES
≠MOV≡≡NXTSID≡≡R1≡≡R1≡≥	034022	016101	000016			MOV	NXTSID(R1),R1		;NO, TRY NEXT
≠BNE≡≥	034026	001372				BNE	3$
≠RTS≡≡PC≡≥	034030	000207				RTS	PC
≥					
≥					PTRSID:
≥					; Given a pointer to a block in R0, returns LOC[space descriptor] in R1.
≥					; Does not destroy R0.
≠MOV≡≡R0≡≡SP≡≥	034032	010046				MOV	R0,-(SP)		;SINCE GETSID WILL MUNCH
≠MOVB≡≡TAGID≡≡R0≡≡R0≡≥	034034	116000	777776			MOVB	TAGID(R0),R0		;THE ID FLAG
≠BIC≡≡R0≡≥	034040	042700	177400			BIC	#177400,R0		;The sign was extended.  Clear it.
≠JSR≡≡PC≡≡GETSID≡≥	034044	004767	777716			JSR	PC,GETSID		;GET SID INTO R1
≠MOV≡≡SP≡≡R0≡≥	034050	012600				MOV	(SP)+,R0		;GET PTR BACK
≠RTS≡≡PC≡≥	034052	000207				RTS	PC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 56
	SMALLB PAL[HAL,HE]	PAGE 13 	SMALL BLOCK ALLOCATOR

≥					; FREBLK, FRESBK
≥					
≥					FREBLK:
≠COMMEN≡≥				    COMMENT ⊗ To free a block whose descriptor is not known:
≥				            MOV     BLOCK,R0        ;R0 ← Block to free
≥				            JSR     PC,FREBLK
≥					    ⊗
≠MOV≡≡SIDLST≡≡R1≡≥	034054	016701	775642			MOV	SIDLST,R1	;FIND THE SPACE
≠BEQ≡≥	034060	001407				BEQ	2$		;THIS CAME FROM
≠CMPB≡≡TAGID≡≡R0≡≡IDFLAG≡≡R1≡≥	034062	126061	777776	000000	1$:	CMPB	TAGID(R0),IDFLAG(R1) ;WAS IT THIS AREA
≠BEQ≡≡FREB.≡≥	034070	001410				BEQ	FREB.		;YES
≠MOV≡≡NXTSID≡≡R1≡≡R1≡≥	034072	016101	000016			MOV	NXTSID(R1),R1	;NO. LOOK AT NEXT
≠BNE≡≥	034076	001371				BNE	1$		;ITERATE
≤HALERR≡≥					2$:	HALERR	FRERMS
≠MOV≡≡FRERMS≡≡SP≡≥	034100	012746	034156			MOV #FRERMS,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	034104	004777	757702			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠RTS≡≡PC≡≥	034110	000207				RTS	PC
≤EVWAIT≡≥					FREB.:	EVWAIT	SBEVT		;CRITICAL REGION STARTS
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	034112	016746	775572			      MOV SBEVT,-(SP)
≥	034116	104010				104010
≠MOV≡≡FFREE≡≡R1≡≡WORD0≡≡R0≡≥	034120	016160	000020	000000		MOV	FFREE(R1),WORD0(R0);FOUND THE AREA, PUT ON FREE CHAIN
≠MOV≡≡R0≡≡FFREE≡≡R1≡≥	034126	010061	000020			MOV	R0,FFREE(R1)
≠INC≡≡NFREE≡≡R1≡≥	034132	005261	000030			INC	NFREE(R1)	;ADJUST COUNTS
≠DEC≡≡NALLOC≡≡R1≡≥	034136	005361	000026			DEC	NALLOC(R1)
≠CLRB≡≡TAG≡≡R0≡≥	034142	105060	777777			CLRB	TAG(R0)		;JUST FOR RANDOMNESS
≤EVSIG≡≥						EVSIG	SBEVT		;END OF CRITICAL REGION
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	034146	016746	775536			      MOV SBEVT,-(SP)
≥	034152	104012				104012
≠RTS≡≡PC≡≥	034154	000207				RTS	PC		;DONE
≤ASCIE≡≥					FRERMS:	ASCIE	/ATTEMPT TO DELETE A BLOCK FROM AN AREA I CANNOT FIND/
≠.ASCIZ≡≥	034156	   101		
≥	034157	   124		
≥	034160	   124		
≥	034161	   105		
≥	034162	   115		
≥	034163	   120		
≥	034164	   124		
≥	034165	   040		
≥	034166	   124		
≥	034167	   117		
≥	034170	   040		
≥	034171	   104		
≥	034172	   105		
≥	034173	   114		
≥	034174	   105		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 57
	SMALLB PAL[HAL,HE]	PAGE 13.1 	SMALL BLOCK ALLOCATOR

≥	034175	   124		
≥	034176	   105		
≥	034177	   040		
≥	034200	   101		
≥	034201	   040		
≥	034202	   102		
≥	034203	   114		
≥	034204	   117		
≥	034205	   103		
≥	034206	   113		
≥	034207	   040		
≥	034210	   106		
≥	034211	   122		
≥	034212	   117		
≥	034213	   115		
≥	034214	   040		
≥	034215	   101		
≥	034216	   116		
≥	034217	   040		
≥	034220	   101		
≥	034221	   122		
≥	034222	   105		
≥	034223	   101		
≥	034224	   040		
≥	034225	   111		
≥	034226	   040		
≥	034227	   103		
≥	034230	   101		
≥	034231	   116		
≥	034232	   116		
≥	034233	   117		
≥	034234	   124		
≥	034235	   040		
≥	034236	   106		
≥	034237	   111		
≥	034240	   116		
≥	034241	   104		
≥	034242	   000		
≥					       .ASCIZ /ATTEMPT TO DELETE A BLOCK FROM AN AREA I CANNOT FIND/
≠.EVEN≡≥		034244			       .EVEN
≥					
≥					FRESBK:
≠COMMEN≡≥				    COMMENT ⊗  To free a block whose descriptor is known:
≥				            MOV     BLOCK,R0         ;R0 ← block to free
≥				            MOV     #SPCDSC,R1       ;R1 ← space descriptor
≥				            JSR     PC,FRESBK
≥					    ⊗
≥					
≠CMPB≡≡TAGID≡≡R0≡≡IDFLAG≡≡R1≡≥	034244	126061	777776	000000		CMPB	TAGID(R0),IDFLAG(R1)	;BE SURE THIS IS OK
≠BEQ≡≡FREB.≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 58
	SMALLB PAL[HAL,HE]	PAGE 13.2 	SMALL BLOCK ALLOCATOR

≥	034252	001717				BEQ	FREB.		;WE WIN
≤HALERR≡≥						HALERR	FREBER
≠MOV≡≡FREBER≡≡SP≡≥	034254	012746	034266			MOV #FREBER,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	034260	004777	757526			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠BR≡≡FREB.≡≥	034264	000712				BR	FREB.		;DO IT ANYHOW IF CONTINUES IT
≥					
≤ASCIE≡≥					FREBER:	ASCIE	/ID DISAGREEMENT FOR FRESBK/
≠.ASCIZ≡≥	034266	   111		
≥	034267	   104		
≥	034270	   040		
≥	034271	   104		
≥	034272	   111		
≥	034273	   123		
≥	034274	   101		
≥	034275	   107		
≥	034276	   122		
≥	034277	   105		
≥	034300	   105		
≥	034301	   115		
≥	034302	   105		
≥	034303	   116		
≥	034304	   124		
≥	034305	   040		
≥	034306	   106		
≥	034307	   117		
≥	034310	   122		
≥	034311	   040		
≥	034312	   106		
≥	034313	   122		
≥	034314	   105		
≥	034315	   123		
≥	034316	   102		
≥	034317	   113		
≥	034320	   000		
≥					       .ASCIZ /ID DISAGREEMENT FOR FRESBK/
≠.EVEN≡≥		034322			       .EVEN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 59
	SMALLB PAL[HAL,HE]	PAGE 14 	SMALL BLOCK ALLOCATOR

≥					; NEWSPC, SETSPC
≥					
≠COMMEN≡≥				COMMENT ⊗ Create a space descriptor.  SZ is the size, IDF the IDFLAG,
≥				NPB the number of blocks per buffer, GCF is set if the area is not to
≥				be collected, NMN is the minimum number of free blocks that GC should
≥				return, NPC is the minimum percent of free blocks that GC should
≥					return.  R0 returns the address of the new space descriptor.  ⊗
≤ROUTIN≡≥					ROUTINE NEWSPC,<SZ,IDF,NPB,GCF,NMN,NPC>
≠.IFNB≡≥					           .IFNB SZ,IDF,NPB,GCF,NMN,NPC
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<SZ,IDF,NPB,GCF,NMN,NPC>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000004			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000006			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000010			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000012			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000014			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<SZ,IDF,NPB,GCF,NMN,NPC>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡SZ≡≥					                  .IFDF SZ
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for SZ
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡SZ≠≥		000014			                   SZ == NNNN
≡NNNN≡≡NNNN≠≥		000012			                   NNNN == NNNN-2
≠.IFDF≡≡IDF≡≥					                  .IFDF IDF
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for IDF
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡IDF≠≥		000012			                   IDF == NNNN
≡NNNN≡≡NNNN≠≥		000010			                   NNNN == NNNN-2
≠.IFDF≡≡NPB≡≥					                  .IFDF NPB
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for NPB
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡NPB≠≥		000010			                   NPB == NNNN
≡NNNN≡≡NNNN≠≥		000006			                   NNNN == NNNN-2
≠.IFDF≡≡GCF≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 60
	SMALLB PAL[HAL,HE]	PAGE 14.1 	SMALL BLOCK ALLOCATOR

≥					                  .IFDF GCF
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for GCF
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡GCF≠≥		000006			                   GCF == NNNN
≡NNNN≡≡NNNN≠≥		000004			                   NNNN == NNNN-2
≠.IFDF≡≡NMN≡≥					                  .IFDF NMN
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for NMN
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡NMN≠≥		000004			                   NMN == NNNN
≡NNNN≡≡NNNN≠≥		000002			                   NNNN == NNNN-2
≠.IFDF≡≡NPC≡≥					                  .IFDF NPC
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for NPC
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡NPC≠≥		000002			                   NPC == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					NEWSPC:
≥					
≠MOV≡≡SPCHDR≡≡R0≡≥	034322	012700	000015			MOV	#SPCHDR/2,R0	;GET A BLOCK OF CORE
≠JSR≡≡PC≡≡GTFREE≡≥	034326	004767	773714			JSR 	PC,GTFREE
≠MOV≡≡SZ≡≡RF≡≡SIZE≡≡R0≡≥	034332	016560	000014	000004		MOV	SZ(RF),SIZE(R0) ;REMEMBER HOW BIG
≠MOV≡≡NPB≡≡RF≡≡NPERB≡≡R0≡≥	034340	016560	000010	000006		MOV	NPB(RF),NPERB(R0) ;
≠MOV≡≡IDF≡≡RF≡≡IDFLAG≡≡R0≡≥	034346	016560	000012	000000		MOV	IDF(RF),IDFLAG(R0) ;
≠MOV≡≡NMN≡≡RF≡≡NMIN≡≡R0≡≥	034354	016560	000004	000012		MOV	NMN(RF),NMIN(R0);
≠MOV≡≡NPC≡≡RF≡≡NPCT≡≡R0≡≥	034362	016560	000002	000014		MOV	NPC(RF),NPCT(R0);
≠MOV≡≡SIDLST≡≡NXTSID≡≡R0≡≥	034370	016760	775326	000016		MOV	SIDLST,NXTSID(R0)  ;LINK ONTO ID CHAIN
≠MOV≡≡R0≡≡SIDLST≡≥	034376	010067	775320			MOV	R0,SIDLST
≠MOV≡≡IDFLAG≡≡R0≡≡R1≡≥	034402	016001	000000		NEWS.:	MOV	IDFLAG(R0),R1	;R1 ← space number
≠CMP≡≡R1≡≡MAXIDF≡≥	034406	020127	000030			CMP	R1,#MAXIDF	;WILL IT FIT INTO TABLE
≠BGT≡≥	034412	003003				BGT	1$		;
≠ASL≡≡R1≡≥	034414	006301				ASL	R1		;YES
≠MOV≡≡R0≡≡SIDTBL≡≡R1≡≥	034416	010061	031724			MOV	R0,SIDTBL(R1)	;PUT INTO TABLE
≠CLR≡≡FFREE≡≡R0≡≥	034422	005060	000020		1$:	CLR	FFREE(R0)	;Zero out other things
≠CLR≡≡FSTBUF≡≡R0≡≥	034426	005060	000022			CLR	FSTBUF(R0)
≠CLR≡≡LSTBUF≡≡R0≡≥	034432	005060	000024			CLR	LSTBUF(R0)
≠CLR≡≡NALLOC≡≡R0≡≥	034436	005060	000026			CLR	NALLOC(R0)
≠CLR≡≡NFREE≡≡R0≡≥	034442	005060	000030			CLR	NFREE(R0)
≠RTS≡≡RF≡≥	034446	000205				RTS	RF		;RETURN
≥					
≠COMMEN≡≥				COMMENT ⊗ Initialize a space descriptor.  SPCADR is its address.  It
≥				will be linked into the ID chanin, put in the SIDTBL if it fits, and
≥					it will be cleared of all buffers.  ⊗
≤ROUTIN≡≥					ROUTINE SETSPC,<SPCADR>
≠.IFNB≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 61
	SMALLB PAL[HAL,HE]	PAGE 14.2 	SMALL BLOCK ALLOCATOR

≥					           .IFNB SPCADR
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<SPCADR>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<SPCADR>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡SPCADR≡≥					                  .IFDF SPCADR
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for SPCADR
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡SPCADR≠≥		000002			                   SPCADR == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					SETSPC:
≠MOV≡≡SPCADR≡≡RF≡≡R0≡≥	034450	016500	000002			MOV	SPCADR(RF),R0	;
≠BR≡≡NEWS.≡≥	034454	000752				BR	NEWS.		;GO INITIALIZE ALL NON-CONSTANT THINGS
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 62
	SMALLB PAL[HAL,HE]	PAGE 15 	SMALL BLOCK ALLOCATOR

≥					; ADDBUF
≥					
≤ROUTIN≡≥					ROUTINE ADDBUF,<SPACE>
≠.IFNB≡≥					           .IFNB SPACE
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<SPACE>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<SPACE>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡SPACE≡≥					                  .IFDF SPACE
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for SPACE
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡SPACE≠≥		000002			                   SPACE == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					ADDBUF:
≥					;ADDS ANOTHER BUFFER TO THE NAMED SPACE
≠MOV≡≡R2≡≡SP≡≥	034456	010246				MOV	R2,-(SP)		;SAVE A REGISTER
≠MOV≡≡R3≡≡SP≡≥	034460	010346				MOV	R3,-(SP)
≠MOV≡≡SPACE≡≡RF≡≡R2≡≥	034462	016502	000002			MOV	SPACE(RF),R2
≠MOV≡≡SIZE≡≡R2≡≡R1≡≥	034466	016201	000004			MOV	SIZE(R2),R1		;CALCULATE WORD REQUIREMENTS
≠INC≡≡R1≡≥	034472	005201				INC	R1			;ONE WORD OVERHEAD FOR TAG & ID BYTES
≠MOV≡≡R1≡≡SP≡≥	034474	010146				MOV	R1,-(SP)		;WILL NEED THIS LATER
≠MUL≡≡NPERB≡≡R2≡≡R1≡≥	034476	070162	000006			MUL	NPERB(R2),R1		;SIZE*NUMBER OF BLOCKS
≠ADD≡≡BUFHDR≡≡R1≡≥	034502	062701	000004			ADD	#BUFHDR/2,R1		;
≠MOV≡≡R1≡≡R0≡≥	034506	010100				MOV	R1,R0			;
≠JSR≡≡PC≡≡GTFREE≡≥	034510	004767	773532			JSR	PC,GTFREE		;GET A BLOCK
≠MOV≡≡LSTBUF≡≡R2≡≡R1≡≥	034514	016201	000024			MOV	LSTBUF(R2),R1		;LINK ONTO CHAIN
≠MOV≡≡R1≡≡PRVBUF≡≡R0≡≥	034520	010160	000002			MOV	R1,PRVBUF(R0)		;LINK BACK
≠BEQ≡≥	034524	001403				BEQ	1$			;
≠MOV≡≡R0≡≡NXTBUF≡≡R1≡≥	034526	010061	000000			MOV	R0,NXTBUF(R1)		;AND PERHAPS FORWARD
≠BR≡≥	034532	000402				BR	2$			;
≠MOV≡≡R0≡≡FSTBUF≡≡R2≡≥	034534	010062	000022		1$:	MOV	R0,FSTBUF(R2)		;IF WAS NO LSTBUF, THEN THIS IS FSTBUF
≠CLR≡≡NXTBUF≡≡R0≡≥	034540	005060	000000		2$:	CLR	NXTBUF(R0)		;CLEAN UP
≠MOV≡≡R0≡≡LSTBUF≡≡R2≡≥	034544	010062	000024			MOV	R0,LSTBUF(R2)		;NEW NEWEST BLOCK
≠MOV≡≡R0≡≡R3≡≥	034550	010003				MOV	R0,R3			;
≠ADD≡≡BUFHDR≡≡R3≡≥	034552	062703	000012			ADD	#2+BUFHDR,R3		;POINTER AT FIRST BLOCK
≠MOV≡≡R3≡≡FSTBLK≡≡R0≡≥	034556	010360	000006			MOV	R3,FSTBLK(R0)		;REMEMBER IT
≠MOV≡≡NPERB≡≡R2≡≡R1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 63
	SMALLB PAL[HAL,HE]	PAGE 15.1 	SMALL BLOCK ALLOCATOR

≥	034562	016201	000006			MOV	NPERB(R2),R1		;
≠ADD≡≡R1≡≡NFREE≡≡R2≡≥	034566	060162	000030			ADD	R1,NFREE(R2)		;New free count
≠ASL≡≡SP≡≥	034572	006316				ASL	(SP)			;NUMBER OF BYTES TO STEP BY
≥					
≠CLRB≡≡TAG≡≡R3≡≥	034574	105063	777777		3$:	CLRB	TAG(R3)			;CLEAR TAG
≠MOVB≡≡IDFLAG≡≡R2≡≡TAGID≡≡R3≡≥	034600	116263	000000	777776		MOVB	IDFLAG(R2),TAGID(R3)	;SET TYPE ID
≠MOV≡≡R3≡≡WORD0≡≡R3≡≥	034606	010363	000000			MOV	R3,WORD0(R3)		;
≠ADD≡≡SP≡≡WORD0≡≡R3≡≥	034612	061663	000000			ADD	(SP),WORD0(R3)		;Point to next block
≠MOV≡≡WORD0≡≡R3≡≡R3≡≥	034616	016303	000000			MOV	WORD0(R3),R3
≠SOB≡≡R1≡≥	034622	077114				SOB	R1,3$			;ITERATE if any left
≥					
≠SUB≡≡SP≡≡R3≡≥	034624	162603				SUB	(SP)+,R3		;Point to last block
≠MOV≡≡R3≡≡LSTBLK≡≡R0≡≥	034626	010360	000004			MOV	R3,LSTBLK(R0)		;R3 NOW POINTS AT LAST BLOCK
≠CLR≡≡WORD0≡≡R3≡≥	034632	005063	000000			CLR	WORD0(R3)		;End of free list
≠MOV≡≡FFREE≡≡R2≡≡R3≡≥	034636	016203	000020			MOV	FFREE(R2),R3		;Find end of free list
≠BNE≡≥	034642	001004				BNE	4$			; If any
≠MOV≡≡FSTBLK≡≡R0≡≡FFREE≡≡R2≡≥	034644	016062	000006	000020		MOV	FSTBLK(R0),FFREE(R2)	;Set up new free list
≠BR≡≥	034652	000407				BR	5$
≠MOV≡≡R3≡≡R2≡≥	034654	010302			4$:	MOV	R3,R2			;Chase through free list
≠MOV≡≡WORD0≡≡R3≡≡R3≡≥	034656	016303	000000			MOV	WORD0(R3),R3
≠BNE≡≥	034662	001374				BNE	4$			; Til end
≠MOV≡≡FSTBLK≡≡R0≡≡WORD0≡≡R2≡≥	034664	016062	000006	000000		MOV	FSTBLK(R0),WORD0(R2)	;Add new blocks to end of free list
≥					
≠MOV≡≡SP≡≡R3≡≥	034672	012603			5$:	MOV	(SP)+,R3		;RESTORE ACS
≠MOV≡≡SP≡≡R2≡≥	034674	012602				MOV	(SP)+,R2
≠RTS≡≡RF≡≥	034676	000205				RTS	RF
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 64
	SMALLB PAL[HAL,HE]	PAGE 16 	SMALL BLOCK ALLOCATOR

≥					; Standard spaces, SBINIT, Marking methods: MCELL, MARKQ
≥					
≥					;Recall that MACRO DEFSPC ID,MMRT,SZ,NPB,GCF,NMN,NPC
≥					
≤DEFSPC≡≥					SCASPC:	DEFSPC	SCLID,MKRTJM,2,10,1,4,15
≠.IFNDF≡≡SCLID≡≥					    .IFNDF SCLID
≥						SIDCNT==SIDCNT+1
≥						SCLID==SIDCNT
≥					    .ENDC
≡II≠≥		034700			    II==.
≠.BLKW≡≡SPCHDR≡≥		034732			    .BLKW SPCHDR/2
≤TT≡≥						TT	IDFLAG,SCLID
≡II≡≡IDFLAG≡≥		034700			        .=II+IDFLAG
≡SCLID≡≡SCLID≡≥	034700	000001			        SCLID
≤TT≡≥						TT	MAPRTN,MKRTJM
≡II≡≡MAPRTN≡≥		034702			        .=II+MAPRTN
≡MKRTJM≡≡MKRTJM≡≥	034702	032020			        MKRTJM
≤TT≡≥						TT	SIZE,2
≡II≡≡SIZE≡≥		034704			        .=II+SIZE
≥	034704	000002			        2
≤TT≡≥						TT	NPERB,10
≡II≡≡NPERB≡≥		034706			        .=II+NPERB
≥	034706	000010			        10
≤TT≡≥						TT	GCFG,1
≡II≡≡GCFG≡≥		034710			        .=II+GCFG
≥	034710	000001			        1
≤TT≡≥						TT	NMIN,4
≡II≡≡NMIN≡≥		034712			        .=II+NMIN
≥	034712	000004			        4
≤TT≡≥						TT	NPCT,15
≡II≡≡NPCT≡≥		034714			        .=II+NPCT
≥	034714	000015			        15
≤TT≡≥						TT	NXTSID,SIDCHN
≡II≡≡NXTSID≡≥		034716			        .=II+NXTSID
≡SIDCHN≡≡SIDCHN≡≥	034716	000000			        SIDCHN
≤TT≡≥						TT	FFREE,0
≡II≡≡FFREE≡≥		034720			        .=II+FFREE
≥	034720	000000			        0
≤TT≡≥						TT	FSTBUF,0
≡II≡≡FSTBUF≡≥		034722			        .=II+FSTBUF
≥	034722	000000			        0
≤TT≡≥						TT	LSTBUF,0
≡II≡≡LSTBUF≡≥		034724			        .=II+LSTBUF
≥	034724	000000			        0
≤TT≡≥						TT	NALLOC,0
≡II≡≡NALLOC≡≥		034726			        .=II+NALLOC
≥	034726	000000			        0
≤TT≡≥						TT	NFREE,0
≡II≡≡NFREE≡≥		034730			        .=II+NFREE
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 65
	SMALLB PAL[HAL,HE]	PAGE 16.1 	SMALL BLOCK ALLOCATOR

≥	034730	000000			        0
≡II≡≡SIDCHN≠≥		034700			    SIDCHN == II
≡II≡≡SPCHDR≡≥		034732			    .=II+SPCHDR
≠.IF2≡≥					      .IF2
≠.IFGE≡≡MAXIDF≡≡SCLID≡≥		000027				.IFGE MAXIDF-SCLID
≤PUTLOC≡≥						  PUTLOC <SCLID*2 + SIDTBL>,SIDCHN
≡II≠≥		034732			        II==.
≡SCLID≡≡SIDTBL≡≥		031726			        .= SCLID*2 + SIDTBL
≡SIDCHN≡≡SIDCHN≡≥	031726	034700			        SIDCHN
≡II≡≥		034732			       .=II
≥						.ENDC
≥					      .ENDC
≤DEFSPC≡≥					VCTSPC:	DEFSPC	VCTID,MKRTJM,10,10,1,4,15
≠.IFNDF≡≡VCTID≡≥					    .IFNDF VCTID
≥						SIDCNT==SIDCNT+1
≥						VCTID==SIDCNT
≥					    .ENDC
≡II≠≥		034732			    II==.
≠.BLKW≡≡SPCHDR≡≥		034764			    .BLKW SPCHDR/2
≤TT≡≥						TT	IDFLAG,VCTID
≡II≡≡IDFLAG≡≥		034732			        .=II+IDFLAG
≡VCTID≡≡VCTID≡≥	034732	000002			        VCTID
≤TT≡≥						TT	MAPRTN,MKRTJM
≡II≡≡MAPRTN≡≥		034734			        .=II+MAPRTN
≡MKRTJM≡≡MKRTJM≡≥	034734	032020			        MKRTJM
≤TT≡≥						TT	SIZE,10
≡II≡≡SIZE≡≥		034736			        .=II+SIZE
≥	034736	000010			        10
≤TT≡≥						TT	NPERB,10
≡II≡≡NPERB≡≥		034740			        .=II+NPERB
≥	034740	000010			        10
≤TT≡≥						TT	GCFG,1
≡II≡≡GCFG≡≥		034742			        .=II+GCFG
≥	034742	000001			        1
≤TT≡≥						TT	NMIN,4
≡II≡≡NMIN≡≥		034744			        .=II+NMIN
≥	034744	000004			        4
≤TT≡≥						TT	NPCT,15
≡II≡≡NPCT≡≥		034746			        .=II+NPCT
≥	034746	000015			        15
≤TT≡≥						TT	NXTSID,SIDCHN
≡II≡≡NXTSID≡≥		034750			        .=II+NXTSID
≡SIDCHN≡≡SIDCHN≡≥	034750	034700			        SIDCHN
≤TT≡≥						TT	FFREE,0
≡II≡≡FFREE≡≥		034752			        .=II+FFREE
≥	034752	000000			        0
≤TT≡≥						TT	FSTBUF,0
≡II≡≡FSTBUF≡≥		034754			        .=II+FSTBUF
≥	034754	000000			        0
≤TT≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 66
	SMALLB PAL[HAL,HE]	PAGE 16.2 	SMALL BLOCK ALLOCATOR

≥						TT	LSTBUF,0
≡II≡≡LSTBUF≡≥		034756			        .=II+LSTBUF
≥	034756	000000			        0
≤TT≡≥						TT	NALLOC,0
≡II≡≡NALLOC≡≥		034760			        .=II+NALLOC
≥	034760	000000			        0
≤TT≡≥						TT	NFREE,0
≡II≡≡NFREE≡≥		034762			        .=II+NFREE
≥	034762	000000			        0
≡II≡≡SIDCHN≠≥		034732			    SIDCHN == II
≡II≡≡SPCHDR≡≥		034764			    .=II+SPCHDR
≠.IF2≡≥					      .IF2
≠.IFGE≡≡MAXIDF≡≡VCTID≡≥		000026				.IFGE MAXIDF-VCTID
≤PUTLOC≡≥						  PUTLOC <VCTID*2 + SIDTBL>,SIDCHN
≡II≠≥		034764			        II==.
≡VCTID≡≡SIDTBL≡≥		031730			        .= VCTID*2 + SIDTBL
≡SIDCHN≡≡SIDCHN≡≥	031730	034732			        SIDCHN
≡II≡≥		034764			       .=II
≥						.ENDC
≥					      .ENDC
≤DEFSPC≡≥					TRNSPC:	DEFSPC	TRNID,MKRTJM,30,4,1,2,15
≠.IFNDF≡≡TRNID≡≥					    .IFNDF TRNID
≥						SIDCNT==SIDCNT+1
≥						TRNID==SIDCNT
≥					    .ENDC
≡II≠≥		034764			    II==.
≠.BLKW≡≡SPCHDR≡≥		035016			    .BLKW SPCHDR/2
≤TT≡≥						TT	IDFLAG,TRNID
≡II≡≡IDFLAG≡≥		034764			        .=II+IDFLAG
≡TRNID≡≡TRNID≡≥	034764	000003			        TRNID
≤TT≡≥						TT	MAPRTN,MKRTJM
≡II≡≡MAPRTN≡≥		034766			        .=II+MAPRTN
≡MKRTJM≡≡MKRTJM≡≥	034766	032020			        MKRTJM
≤TT≡≥						TT	SIZE,30
≡II≡≡SIZE≡≥		034770			        .=II+SIZE
≥	034770	000030			        30
≤TT≡≥						TT	NPERB,4
≡II≡≡NPERB≡≥		034772			        .=II+NPERB
≥	034772	000004			        4
≤TT≡≥						TT	GCFG,1
≡II≡≡GCFG≡≥		034774			        .=II+GCFG
≥	034774	000001			        1
≤TT≡≥						TT	NMIN,2
≡II≡≡NMIN≡≥		034776			        .=II+NMIN
≥	034776	000002			        2
≤TT≡≥						TT	NPCT,15
≡II≡≡NPCT≡≥		035000			        .=II+NPCT
≥	035000	000015			        15
≤TT≡≥						TT	NXTSID,SIDCHN
≡II≡≡NXTSID≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 67
	SMALLB PAL[HAL,HE]	PAGE 16.3 	SMALL BLOCK ALLOCATOR

≥		035002			        .=II+NXTSID
≡SIDCHN≡≡SIDCHN≡≥	035002	034732			        SIDCHN
≤TT≡≥						TT	FFREE,0
≡II≡≡FFREE≡≥		035004			        .=II+FFREE
≥	035004	000000			        0
≤TT≡≥						TT	FSTBUF,0
≡II≡≡FSTBUF≡≥		035006			        .=II+FSTBUF
≥	035006	000000			        0
≤TT≡≥						TT	LSTBUF,0
≡II≡≡LSTBUF≡≥		035010			        .=II+LSTBUF
≥	035010	000000			        0
≤TT≡≥						TT	NALLOC,0
≡II≡≡NALLOC≡≥		035012			        .=II+NALLOC
≥	035012	000000			        0
≤TT≡≥						TT	NFREE,0
≡II≡≡NFREE≡≥		035014			        .=II+NFREE
≥	035014	000000			        0
≡II≡≡SIDCHN≠≥		034764			    SIDCHN == II
≡II≡≡SPCHDR≡≥		035016			    .=II+SPCHDR
≠.IF2≡≥					      .IF2
≠.IFGE≡≡MAXIDF≡≡TRNID≡≥		000025				.IFGE MAXIDF-TRNID
≤PUTLOC≡≥						  PUTLOC <TRNID*2 + SIDTBL>,SIDCHN
≡II≠≥		035016			        II==.
≡TRNID≡≡SIDTBL≡≥		031732			        .= TRNID*2 + SIDTBL
≡SIDCHN≡≡SIDCHN≡≥	031732	034764			        SIDCHN
≡II≡≥		035016			       .=II
≥						.ENDC
≥					      .ENDC
≤DEFSPC≡≥					CELSPC:	DEFSPC	CELID,MKRTJM,2,10,1,4,15
≠.IFNDF≡≡CELID≡≥					    .IFNDF CELID
≥						SIDCNT==SIDCNT+1
≥						CELID==SIDCNT
≥					    .ENDC
≡II≠≥		035016			    II==.
≠.BLKW≡≡SPCHDR≡≥		035050			    .BLKW SPCHDR/2
≤TT≡≥						TT	IDFLAG,CELID
≡II≡≡IDFLAG≡≥		035016			        .=II+IDFLAG
≡CELID≡≡CELID≡≥	035016	000004			        CELID
≤TT≡≥						TT	MAPRTN,MKRTJM
≡II≡≡MAPRTN≡≥		035020			        .=II+MAPRTN
≡MKRTJM≡≡MKRTJM≡≥	035020	032020			        MKRTJM
≤TT≡≥						TT	SIZE,2
≡II≡≡SIZE≡≥		035022			        .=II+SIZE
≥	035022	000002			        2
≤TT≡≥						TT	NPERB,10
≡II≡≡NPERB≡≥		035024			        .=II+NPERB
≥	035024	000010			        10
≤TT≡≥						TT	GCFG,1
≡II≡≡GCFG≡≥		035026			        .=II+GCFG
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 68
	SMALLB PAL[HAL,HE]	PAGE 16.4 	SMALL BLOCK ALLOCATOR

≥	035026	000001			        1
≤TT≡≥						TT	NMIN,4
≡II≡≡NMIN≡≥		035030			        .=II+NMIN
≥	035030	000004			        4
≤TT≡≥						TT	NPCT,15
≡II≡≡NPCT≡≥		035032			        .=II+NPCT
≥	035032	000015			        15
≤TT≡≥						TT	NXTSID,SIDCHN
≡II≡≡NXTSID≡≥		035034			        .=II+NXTSID
≡SIDCHN≡≡SIDCHN≡≥	035034	034764			        SIDCHN
≤TT≡≥						TT	FFREE,0
≡II≡≡FFREE≡≥		035036			        .=II+FFREE
≥	035036	000000			        0
≤TT≡≥						TT	FSTBUF,0
≡II≡≡FSTBUF≡≥		035040			        .=II+FSTBUF
≥	035040	000000			        0
≤TT≡≥						TT	LSTBUF,0
≡II≡≡LSTBUF≡≥		035042			        .=II+LSTBUF
≥	035042	000000			        0
≤TT≡≥						TT	NALLOC,0
≡II≡≡NALLOC≡≥		035044			        .=II+NALLOC
≥	035044	000000			        0
≤TT≡≥						TT	NFREE,0
≡II≡≡NFREE≡≥		035046			        .=II+NFREE
≥	035046	000000			        0
≡II≡≡SIDCHN≠≥		035016			    SIDCHN == II
≡II≡≡SPCHDR≡≥		035050			    .=II+SPCHDR
≠.IF2≡≥					      .IF2
≠.IFGE≡≡MAXIDF≡≡CELID≡≥		000024				.IFGE MAXIDF-CELID
≤PUTLOC≡≥						  PUTLOC <CELID*2 + SIDTBL>,SIDCHN
≡II≠≥		035050			        II==.
≡CELID≡≡SIDTBL≡≥		031734			        .= CELID*2 + SIDTBL
≡SIDCHN≡≡SIDCHN≡≥	031734	035016			        SIDCHN
≡II≡≥		035050			       .=II
≥						.ENDC
≥					      .ENDC
≤DEFSPC≡≥					ENVSPC:	DEFSPC	ENVID,MKRTJM,30,3,1,1,10
≠.IFNDF≡≡ENVID≡≥					    .IFNDF ENVID
≥						SIDCNT==SIDCNT+1
≥						ENVID==SIDCNT
≥					    .ENDC
≡II≠≥		035050			    II==.
≠.BLKW≡≡SPCHDR≡≥		035102			    .BLKW SPCHDR/2
≤TT≡≥						TT	IDFLAG,ENVID
≡II≡≡IDFLAG≡≥		035050			        .=II+IDFLAG
≡ENVID≡≡ENVID≡≥	035050	000005			        ENVID
≤TT≡≥						TT	MAPRTN,MKRTJM
≡II≡≡MAPRTN≡≥		035052			        .=II+MAPRTN
≡MKRTJM≡≡MKRTJM≡≥	035052	032020			        MKRTJM
≤TT≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 69
	SMALLB PAL[HAL,HE]	PAGE 16.5 	SMALL BLOCK ALLOCATOR

≥						TT	SIZE,30
≡II≡≡SIZE≡≥		035054			        .=II+SIZE
≥	035054	000030			        30
≤TT≡≥						TT	NPERB,3
≡II≡≡NPERB≡≥		035056			        .=II+NPERB
≥	035056	000003			        3
≤TT≡≥						TT	GCFG,1
≡II≡≡GCFG≡≥		035060			        .=II+GCFG
≥	035060	000001			        1
≤TT≡≥						TT	NMIN,1
≡II≡≡NMIN≡≥		035062			        .=II+NMIN
≥	035062	000001			        1
≤TT≡≥						TT	NPCT,10
≡II≡≡NPCT≡≥		035064			        .=II+NPCT
≥	035064	000010			        10
≤TT≡≥						TT	NXTSID,SIDCHN
≡II≡≡NXTSID≡≥		035066			        .=II+NXTSID
≡SIDCHN≡≡SIDCHN≡≥	035066	035016			        SIDCHN
≤TT≡≥						TT	FFREE,0
≡II≡≡FFREE≡≥		035070			        .=II+FFREE
≥	035070	000000			        0
≤TT≡≥						TT	FSTBUF,0
≡II≡≡FSTBUF≡≥		035072			        .=II+FSTBUF
≥	035072	000000			        0
≤TT≡≥						TT	LSTBUF,0
≡II≡≡LSTBUF≡≥		035074			        .=II+LSTBUF
≥	035074	000000			        0
≤TT≡≥						TT	NALLOC,0
≡II≡≡NALLOC≡≥		035076			        .=II+NALLOC
≥	035076	000000			        0
≤TT≡≥						TT	NFREE,0
≡II≡≡NFREE≡≥		035100			        .=II+NFREE
≥	035100	000000			        0
≡II≡≡SIDCHN≠≥		035050			    SIDCHN == II
≡II≡≡SPCHDR≡≥		035102			    .=II+SPCHDR
≠.IF2≡≥					      .IF2
≠.IFGE≡≡MAXIDF≡≡ENVID≡≥		000023				.IFGE MAXIDF-ENVID
≤PUTLOC≡≥						  PUTLOC <ENVID*2 + SIDTBL>,SIDCHN
≡II≠≥		035102			        II==.
≡ENVID≡≡SIDTBL≡≥		031736			        .= ENVID*2 + SIDTBL
≡SIDCHN≡≡SIDCHN≡≥	031736	035050			        SIDCHN
≡II≡≥		035102			       .=II
≥						.ENDC
≥					      .ENDC
≥					
≠COMMEN≡≥					COMMENT ⊗ Thus SCLID=1, VCTID=2, TRNID=3 ⊗
≥					
≤ROUTIN≡≥					ROUTINE SBINIT
≠.IFNB≡≥					           .IFNB 
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 70
	SMALLB PAL[HAL,HE]	PAGE 16.6 	SMALL BLOCK ALLOCATOR

≥						    NNNN==0
≥						       .IRP II,<>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≥						       .IRP II,<>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≥						   .ENDC
≥					SBINIT:
≥					; Initializes the small block allocator with the standard spaces.
≤EVMAK≡≥						EVMAK			;Initialize the small block interlock event
≥	035102	104004				104004
≠MOV≡≡SP≡≡SBEVT≡≥	035104	012667	774600			MOV (SP)+,SBEVT		;
≤EVSIG≡≥						EVSIG SBEVT		;
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	035110	016746	774574			      MOV SBEVT,-(SP)
≥	035114	104012				104012
≠MOV≡≡SIDHED≡≡SIDLST≡≥	035116	012767	035050	774576		MOV #SIDHED,SIDLST	;
≠CLR≡≡GCOK≡≥	035124	005067	774564			CLR GCOK		;Garbage collect initially OK.
≠CLR≡≡GCDONE≡≥	035130	005067	774562			CLR GCDONE		;
≠MOV≡≡SIDHED≡≡R2≡≥	035134	012702	035050			MOV #SIDHED,R2		;R2 ← First space
≠BEQ≡≥	035140	001412				BEQ 2$			;If any
≤CALL≡≥					1$:	CALL SETSPC,<R2>	;Initialize this space
≠MOV≡≡RF≡≡SP≡≥	035142	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R2
≠.IRP≡≥						       .IRP II,<R2>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R2≡≡SP≡≥	035144	010246					MOV	R2,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	035146	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	035152	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡SETSPC≡≥	035154	004767	777270			JSR	PC,SETSPC		;Call the routine
≠MOV≡≡NXTSID≡≡R2≡≡R2≡≥	035160	016202	000016			MOV NXTSID(R2),R2	;R2 ← Next space
≠BNE≡≥	035164	001366				BNE 1$			;If any
≠CLR≡≡MMETHS≡≥	035166	005067	774520		2$:	CLR MMETHS		;Initialize the marking methods
≠MOV≡≡MGNDSM≡≡R0≡≥	035172	012700	035214			MOV #MGNDSM,R0		;Link in the GNODE marking method
≠JSR≡≡PC≡≡LNKMTH≡≥	035176	004767	774640			JSR PC,LNKMTH		;
≠MOV≡≡MINTSM≡≡R0≡≥	035202	012700	035220			MOV #MINTSM,R0		;Link in the interpreter stack marking method
≠JSR≡≡PC≡≡LNKMTH≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 71
	SMALLB PAL[HAL,HE]	PAGE 16.7 	SMALL BLOCK ALLOCATOR

≥	035206	004767	774630			JSR PC,LNKMTH		;
≠RTS≡≡RF≡≥	035212	000205				RTS RF
≥					
≤MMETH≡≥					MGNDSM:	MMETH MGNDS		;In file GRAPHS.PAL
≡MGNDS≡≡MGNDS≡≥	035214	063056				MGNDS
≥	035216	000000				0
≥						
≤MMETH≡≥					MINTSM:	MMETH MINTS		;In file INTERP.PAL
≡MINTS≡≡MINTS≡≥	035220	035344				MINTS
≥	035222	000000				0
≥					
≥					MCELL:	
≠COMMEN≡≥				COMMENT ⊗ Marking method for a cell list.  Takes pointer to list in
≥				R0, and marks all the way down, and returns pointer in R0, since
≥					compacting may move it.  ⊗
≠TST≡≡R0≡≥	035224	005700				TST R0			;Empty?
≠BEQ≡≥	035226	001416				BEQ 2$			;Yes.
≠MOV≡≡R2≡≡SP≡≥	035230	010246				MOV R2,-(SP)		;Save R2
≠JSR≡≡PC≡≡MARKQ≡≥	035232	004767	000030			JSR PC,MARKQ		;Mark cell
≠MOV≡≡R0≡≡SP≡≥	035236	010046				MOV R0,-(SP)		;Save list header
≠MOV≡≡R0≡≡R2≡≥	035240	010002			1$:	MOV R0,R2		;Save new pointer
≠MOV≡≡CDR≡≡R2≡≡R0≡≥	035242	016200	000002			MOV CDR(R2),R0		;Mark the rest of the list iteratively
≠JSR≡≡PC≡≡MARKQ≡≥	035246	004767	000014			JSR PC,MARKQ		;Mark this cell
≠MOV≡≡R0≡≡CDR≡≡R2≡≥	035252	010062	000002			MOV R0,CDR(R2)		;replace pointer.
≠BNE≡≥	035256	001370				BNE 1$			;Loop til end of list
≠MOV≡≡SP≡≡R0≡≥	035260	012600				MOV (SP)+,R0		;Restore R0 ← pointer
≠MOV≡≡SP≡≡R2≡≥	035262	012602				MOV (SP)+,R2		;Restore R2
≠RTS≡≡PC≡≥	035264	000207			2$:	RTS PC			;Done
≥					
≥					MARKQ:
≠COMMEN≡≥				COMMENT ⊗ R0 holds LOC[small block].  Mark it if it is really a small
≥				block; but be careful, since it may be a constant.  Return it in R0,
≥					since compacting may have moved it.  ⊗
≠CMP≡≡R0≡≡FREEST≡≥	035266	020027	015116			CMP R0,#FREEST	;Make sure that it points into free storage.
≠BLE≡≥	035272	003405				BLE 1$		; (it may be a program constant)
≠CMP≡≡R0≡≡FREEND≡≥	035274	020027	030114			CMP R0,#FREEND	;
≠BGE≡≥	035300	002002				BGE 1$		;
≠JSR≡≡PC≡≡MARKR0≡≥	035302	004767	774516			JSR PC,MARKR0	;Get it marked
≠RTS≡≡PC≡≥	035306	000207			1$:	RTS PC		;Done
≥					
≠.IFNZ≡≡SMBDBG≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 72
	SMALLB PAL[HAL,HE]	PAGE 17 	SMALL BLOCK ALLOCATOR

≥		000000			.IFNZ	SMBDBG		;Test routine
≥					
≥					
≥					FSTEST:	CALL	SBINIT
≥						MOV	#20,R2
≥						MOV	#VCTARA,R3
≥					FST.1:	MOV	#VCTID,R0
≥						JSR	PC,GETBLK
≥					FST.2:	MOV	R0,(R3)+
≥						DEC	R2
≥						BGT	FST.1
≥					FST.3:	MOV	#13,R2
≥					FST.4:	MOV	-(R3),R0
≥						JSR	PC,FREBLK
≥						DEC	R2
≥						BGT	FST.4
≥					FST.5:	MOV	#17,R2
≥					FST.6:	MOV	#VCTID,R0
≥						JSR	PC,GETBLK
≥						MOV	R0,(R3)+
≥						DEC	R2
≥						BGT	FST.6
≥					FST.10:	MOV	#TSTMTH,R0
≥						JSR	PC,LNKMTH
≥						MOV	R3,VCTUB
≥						SUB	#2,VCTUB
≥						MOV	#VCTARA,VCTLB
≥						MOV	#-1,GCOK
≥						CALL	GC
≥					FST.11:	MOV	#10,R2
≥					FST.12:	MOV	#VCTSPC,R0
≥						JSR	PC,GETSBK
≥						DEC	R2
≥						BGT	FST.12
≥					
≥						HALERR	DNMSG
≥					
≥					DNMSG:	ASCIE	</
≥					WELL HOW DID WE DO?/>
≥					
≥					VCTARA:	.BLKW	200
≥					VCTUB:	0
≥					VCTLB:	0
≥					
≥					TSTMTH:	MMETH	TSTRTN
≥					
≥					ROUTINE TSTRTN,<RTN>
≥						MOV	R2,-(SP)
≥						MOV	VCTLB,R2
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 73
	SMALLB PAL[HAL,HE]	PAGE 17.1 	SMALL BLOCK ALLOCATOR

≥					TST.R1:	CMP	R2,VCTUB
≥						BGT	TSTRTS
≥						MOV	(R2),R0
≥						JSR	PC,MARKR0
≥						MOV	R0,(R2)+
≥						BR	TST.R1
≥					TSTRTS:	MOV	(SP)+,R2
≥						RTS	RF
≥					
≥					.ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 74
	SMALLB PAL[HAL,HE]	PAGE 18 	SMALL BLOCK ALLOCATOR

≥					; Known bugs
≥					
≠COMMEN≡≥				COMMENT ⊗ Garbage collect will fail to mark, and therefore wrongfully
≥				collect, those small blocks which have just been allocated and are
≥				sitting in registers somewhere.  The proper fix to this is that
≥				GETSBK and GETBLK should turn on one level of garbage collect
≥				inhibition, and let the caller turn it off when he has stowed away
≥				the pointer in some place known to the marking routines. (This has
≥				been done using SBEVT to do the interlocking. ARG 11/76)  A similar
≥				problem could occur when someone removes a pointer from the known
≥				places before he is really finished with the small block.  This is
≥				fixed only by careful identification and rectification of such pieces
≥				of code.  
≥				
≥				When marking those things pointed to by interpeter stacks, the MINT
≥				routine looks for a zero entry on the stack.  This could fail, or get
≥				more than wanted. (Should be okay now. Interp keeps sticking a zero
≥				on the top just prior to interpreting the next pseudo-code instruction.)
≥					⊗
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 75
	HAL PAL[HAL,HE]	PAGE 2.3 	SMALL BLOCK ALLOCATOR

≥					.ENDC
≥					
≠.IFNZ≡≡INTLOA≡≥		000001			.IFNZ INTLOAD		;The interpreter
≠.INSRT≡≥					    .INSRT INTERP.PAL[HAL,HE]
≠COMMEN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 76
	INTERP PAL[HAL,HE]	PAGE 1 	SMALL BLOCK ALLOCATOR

≥				COMMENT ⊗   VALID 00029 PAGES
≥				C REC  PAGE   DESCRIPTION
≥				C00001 00001
≥				C00004 00002	.SBTTL Interpreter	Data structures
≥				C00010 00003	INTINIT, NEWENV, MINTS
≥				C00013 00004	Interpreter itself: INTERP
≥				C00019 00005	  GETARG, GETSCA, GETVEC, GETTRN
≥				C00024 00006	Variable declaration:  MVAR, KVAR
≥				C00027 00007	Stack ops: GTVAL, IGTVAL, CHNGE, ICHNGE, PUSH, POP, COPY, REPLACE, FLUSH
≥				C00033 00008	Global reference routines GLBLNK, GLOBSR.
≥				C00038 00009	Flow-of-control: PROC, RETURN, ABORT, GODDT
≥				C00045 00010	  FORCHK, JUMP, JUMPC
≥				C00049 00011	  SPAWN, SPROUT, TERMINATE
≥				C00057 00012	Calculator routines: MEXP, MCLC, DCLC, ENDCLC
≥				C00062 00013	Changer routines: MCHG, GTOLD, GTNEW
≥				C00065 00014	Booleans: SLE,SLT,SGE,SGT,SEQ,SNE,AND,LOR,NOT
≥				C00070 00015	return scalars: SADD, SSUB, SMUL, SDIV, SNEG, VDOT, PVDOT, VMAG, SSBRTN
≥				C00077 00016	Vector utilities:  UNITV, CROSV
≥				C00083 00017	TRANS extraction routines: TPOS, TORIEN, TAXIS, TMAGN
≥				C00091 00018	Return vectors: SVMUL, TVMUL, VMAKE, VADD, VSUB
≥				C00096 00019	Return a trans: TMAKE, TVADD, TVSUB, TTMUL, TINVRT, VSAXWR
≥				C00108 00020	Motion:  MOVE, CENTER, STOP, WHERE, NOTICE
≥				C00116 00021	Condition monitors:  CMMAK 
≥				C00122 00022	  CMENBL, CMDSBL, CMDEST, CMTRIG, CMSKED, CMUNCR
≥				C00129 00023	Force expressions.  Data structures. TABOFS, FMBLK, MAKFORCE, DESFORCE
≥				C00137 00024	  GETFORCE, MAKRT
≥				C00145 00025	Events:  MAKEVT, SIGNAL, WAITE, DESEVT, PAUSE
≥				C00150 00026	Output routines:  PRINT, VALPRN, VARPRN, TACKVAL, TYPVAL, CVFX
≥				C00156 00027	  BREAK, NOOP, TOPAL
≥				C00158 00028	Initialization psops:  PROG, ENDP, FIXIT
≥				C00164 00029	BUGS
≥				C00165 ENDMK
≥					C⊗;
≠.SBTTL≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 77
	INTERP PAL[HAL,HE]	PAGE 2 	Interpreter	;Data structures

≥					.SBTTL Interpreter	;Data structures
≥					
≠COMMEN≡≥				COMMENT ⊗
≥				Register uses in the interpreter:
≥					R5	used by some routines as the display register
≥				 	R4	points to interpreter status block
≥				 	R3	interpreter stack pointer
≥				 	R2	not used by the main interpreter loop.  Can be munged by
≥				                    any primary interpreter routine.
≥				
≥				Each interpreter has a stack which it uses to store pointers to
≥				currently "open" variables.  During the course of a calculation,
≥				operands and temporary result cells will be open in this fashion. 
≥				The "interpreter stack" is pointed to by R3. When a new interpreter
≥				is sprouted, it is given a new stack area. Each interpreter has
≥				certain status information which facilitates transfer of control
≥				between interpreters.  This information is kept in the interpreter
≥				status block, which is always pointed to by R4.  Most important are
≥				the IPC, the Interpreter Program Counter, the ENV, which points to
≥				the local environment, and LEV, which stores the current lexical
≥				level. 
≥				
≥				Each procedure has an environment, which is a data area holding
≥				information vital to that procedure.  This includes pointers to all
≥				the variables local to that procedure, and return information.
≥				The environments are administered under the small block allocator
≥				with garbage collection.
≥					 ⊗
≥					
≡INSTSZ≠≥		000020				INSTSZ == 20	;Size of an interpreter stack
≥					
≥					;Interpreter status block
≡II≠≥		000000				II == 0
≤XX≡≥						XX IPC		;Interpreter program counter. Leave this as first field!
≠.IFDF≡≡IPC≡≥						   .IFDF IPC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using IPC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡IPC≠≥		000000				    IPC == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX NXTINT 	;Next interpreter in the list.  For GC of the stacks.
≠.IFDF≡≡NXTINT≡≥						   .IFDF NXTINT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NXTINT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NXTINT≠≥		000002				    NXTINT == II
≡II≡≡II≠≥		000004				    II == II+2
≤XX≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 78
	INTERP PAL[HAL,HE]	PAGE 2.1 	Interpreter	;Data structures

≥						XX STKBAS 	;Location of start of stack area.  Needed
≠.IFDF≡≡STKBAS≡≥						   .IFDF STKBAS
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using STKBAS in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡STKBAS≠≥		000004				    STKBAS == II
≡II≡≡II≠≥		000006				    II == II+2
≥								;for eventual reclamation.
≤XX≡≥						XX ENV		;Location of local environment
≠.IFDF≡≡ENV≡≥						   .IFDF ENV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using ENV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡ENV≠≥		000006				    ENV == II
≡II≡≡II≠≥		000010				    II == II+2
≤XX≡≥						XX LEV		;Lexical level of current execution
≠.IFDF≡≡LEV≡≥						   .IFDF LEV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using LEV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡LEV≠≥		000010				    LEV == II
≡II≡≡II≠≥		000012				    II == II+2
≤XX≡≥						XX STA		;Status bits for condition codes:  0 means all well.
≠.IFDF≡≡STA≡≥						   .IFDF STA
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using STA in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡STA≠≥		000012				    STA == II
≡II≡≡II≠≥		000014				    II == II+2
≤XX≡≥						XX PCB		;Location of process control block (for reclamation)
≠.IFDF≡≡PCB≡≥						   .IFDF PCB
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using PCB in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡PCB≠≥		000014				    PCB == II
≡II≡≡II≠≥		000016				    II == II+2
≤XX≡≥						XX EVT		;The event to signal as this interpreter goes away
≠.IFDF≡≡EVT≡≥						   .IFDF EVT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using EVT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡EVT≠≥		000016				    EVT == II
≡II≡≡II≠≥		000020				    II == II+2
≤XX≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 79
	INTERP PAL[HAL,HE]	PAGE 2.2 	Interpreter	;Data structures

≥						XX CMCB		;Pointer to c-m control block if this is a checker or a body
≠.IFDF≡≡CMCB≡≥						   .IFDF CMCB
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using CMCB in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡CMCB≠≥		000020				    CMCB == II
≡II≡≡II≠≥		000022				    II == II+2
≤XX≡≥						XX OLDV		;The "old value" used by changers
≠.IFDF≡≡OLDV≡≥						   .IFDF OLDV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using OLDV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡OLDV≠≥		000022				    OLDV == II
≡II≡≡II≠≥		000024				    II == II+2
≤XX≡≥						XX NEWV		;The "new value" used by changers
≠.IFDF≡≡NEWV≡≥						   .IFDF NEWV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NEWV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NEWV≠≥		000024				    NEWV == II
≡II≡≡II≠≥		000026				    II == II+2
≠.IFNZ≡≡ALAID≡≥		000001			    .IFNZ ALAID		;Special debugging information
≤XX≡≥						XX INTNAM	;Name of the interpreter
≠.IFDF≡≡INTNAM≡≥						   .IFDF INTNAM
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using INTNAM in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡INTNAM≠≥		000026				    INTNAM == II
≡II≡≡II≠≥		000030				    II == II+2
≤XX≡≥						XX INTMA1	;  two words
≠.IFDF≡≡INTMA1≡≥						   .IFDF INTMA1
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using INTMA1 in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡INTMA1≠≥		000030				    INTMA1 == II
≡II≡≡II≠≥		000032				    II == II+2
≤XX≡≥						XX DEBMOD	;The mode bits for debugging.
≠.IFDF≡≡DEBMOD≡≥						   .IFDF DEBMOD
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using DEBMOD in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡DEBMOD≠≥		000032				    DEBMOD == II
≡II≡≡II≠≥		000034				    II == II+2
≡ALDSS≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 80
	INTERP PAL[HAL,HE]	PAGE 2.3 	Interpreter	;Data structures

≥		000001					ALDSS == 1	;1 => Single step mode
≡ASDTE≠≥		000002					ASDTE == 2	;1 => Terminate this interpeter
≤XX≡≥						XX WAKEVT	;Event to wait on during halts
≠.IFDF≡≡WAKEVT≡≥						   .IFDF WAKEVT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using WAKEVT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡WAKEVT≠≥		000034				    WAKEVT == II
≡II≡≡II≠≥		000036				    II == II+2
≥					    .ENDC
≡II≡≡ISBS≠≥		000017				ISBS == II/2	;Size (in words) of interpreter status block
≥					
≥					;Fixed fields in the environment of each process
≡II≠≥		000000				II == 0
≤XX≡≥						XX SLINK 	;Pointer to environment of next (outer, lower
≠.IFDF≡≡SLINK≡≥						   .IFDF SLINK
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using SLINK in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡SLINK≠≥		000000				    SLINK == II
≡II≡≡II≠≥		000002				    II == II+2
≥								;  numbered) block
≤XX≡≥						XX OLEV		;Old level.  The lexical level of calling process.
≠.IFDF≡≡OLEV≡≥						   .IFDF OLEV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using OLEV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡OLEV≠≥		000002				    OLEV == II
≡II≡≡II≠≥		000004				    II == II+2
≤XX≡≥						XX OENV		;Old environment, the one for the calling process.
≠.IFDF≡≡OENV≡≥						   .IFDF OENV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using OENV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡OENV≠≥		000004				    OENV == II
≡II≡≡II≠≥		000006				    II == II+2
≤XX≡≥						XX OIPC		;Old IPC.  Program counter for calling process.
≠.IFDF≡≡OIPC≡≥						   .IFDF OIPC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using OIPC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡OIPC≠≥		000006				    OIPC == II
≡II≡≡II≠≥		000010				    II == II+2
≤XX≡≥						XX LVARS	;First location where pointers to local variables go
≠.IFDF≡≡LVARS≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 81
	INTERP PAL[HAL,HE]	PAGE 2.4 	Interpreter	;Data structures

≥						   .IFDF LVARS
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using LVARS in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡LVARS≠≥		000010				    LVARS == II
≡II≡≡II≠≥		000012				    II == II+2
≥					
≥					;   Mechanism bits.
≡YARM≠≥		000001				YARM == 1
≡YHAND≠≥		000002				YHAND == 2
≡BARM≠≥		000004				BARM == 4
≡BHAND≠≥		000010				BHAND == 10
≡YARM≡≡BARM≡≡ANARM≠≥		000005				ANARM == YARM + BARM
≡YHAND≡≡BHAND≡≡AHAND≠≥		000012				AHAND == YHAND + BHAND
≥					
≥					;    Servo bits.
≡YARMSB≠≥		176000				YARMSB == 176000
≡YHANDS≠≥		001000				YHANDSB == 1000
≡BARMSB≠≥		000770				BARMSB == 770
≡BHANDS≠≥		000004				BHANDSB == 4
≥					
≥					;   Table offsets for various mechanisms.
≡OFYARM≠≥		000000				OFYARM == 0
≡OFYHAN≠≥		000014				OFYHAND == 6*2
≡OFBARM≠≥		000016				OFBARM == 7*2
≡OFBHAN≠≥		000032				OFBHAND == 15*2
≥					
≥					;  Environment offsets for the various mechanisms
≠.IFNZ≡≡YELLOW≡≥		000000			    .IFNZ YELLOW
≥						YAOFST == 10
≥						YHOFST == 12
≥					    .ENDC
≡BAOFST≠≥		000014				BAOFST == 14
≡BHOFST≠≥		000016				BHOFST == 16
≥					
≥					;  Environment offsets for the calculators of those mechanisms
≠.IFNZ≡≡YELLOW≡≥		000000			    .IFNZ YELLOW
≥						YACOFS == 20
≥						YHCOFS == 22
≥						BACOFS == 24
≥						BHCOFS == 26
≥					    .IFF
≡BACOFS≠≥		000010				BACOFS == 10 
≡BHCOFS≠≥		000012				BHCOFS == 12
≥					    .ENDC
≥					
≥					;  Environment offsets for the deproach variables
≡BDEPRO≠≥		000030				BDEPROACH == 30
≡YDEPRO≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 82
	INTERP PAL[HAL,HE]	PAGE 2.5 	Interpreter	;Data structures

≥		000032				YDEPROACH == 32
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 83
	INTERP PAL[HAL,HE]	PAGE 3 	Interpreter	;Data structures

≥					;INTINIT, NEWENV, MINTS
≥					
≥	035310	000000			INTEVT:	0		;The event that interlocks references to ISTBLK.
≥	035312	000000			GLBEVT:	0		;The event that interlocks references to GLBTAB.
≥					
≥					INTINIT:	;Initializes the above events
≤EVMAK≡≥						EVMAK		;Initialize the INTEVT.
≥	035314	104004				104004
≠MOV≡≡SP≡≡INTEVT≡≥	035316	011667	777766			MOV (SP),INTEVT;
≤EVSIG≡≥						EVSIG 		;
≤.ARG≡≥						  .ARG 
≠.LIF≡≥						    .LIF NB 
≥						      MOV ,-(SP)
≥	035322	104012				104012
≤EVMAK≡≥						EVMAK		;Initialize the GLBEVT.
≥	035324	104004				104004
≠MOV≡≡SP≡≡GLBEVT≡≥	035326	011667	777760			MOV (SP),GLBEVT	;
≤EVSIG≡≥						EVSIG		;
≤.ARG≡≥						  .ARG 
≠.LIF≡≥						    .LIF NB 
≥						      MOV ,-(SP)
≥	035332	104012				104012
≠MOV≡≡GLBTAB≡≡GLBEND≡≥	035334	012767	037502	002226		MOV #GLBTAB,GLBEND	;Initialize GLBEND.  This wipes out all globals.
≠RTS≡≡PC≡≥	035342	000207				RTS PC		;Done
≥					
≥					MINTS:	;Marking method for interpeters
≠MOV≡≡R2≡≡SP≡≥	035344	010246				MOV R2,-(SP)		;Save R2
≠MOV≡≡R3≡≡SP≡≥	035346	010346				MOV R3,-(SP)		;Save R3
≤EVWAIT≡≥						EVWAIT INTEVT		;Enter critical region
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	035350	016746	777734			      MOV INTEVT,-(SP)
≥	035354	104010				104010
≠MOV≡≡NXTINT≡≡ISTBLK≡≡R2≡≥	035356	016702	025642			MOV NXTINT+ISTBLK,R2	;R2 ← LOC[first real interpeter status block]
≠BEQ≡≥	035362	001450				BEQ 6$			;If none, then done
≥					
≥						;mark the stack
≠MOV≡≡STKBAS≡≡R2≡≡R3≡≥	035364	016203	000004		1$:	MOV STKBAS(R2),R3	;R3 ← LOC[interpreter stack base]
≠ADD≡≡INSTSZ≡≡R3≡≥	035370	062703	000040			ADD #2*INSTSZ,R3	;R3 ← LOC[verge of new stack] (INSTSZ is in bytes)
≠MOV≡≡R3≡≡R0≡≥	035374	014300			2$:	MOV -(R3),R0		;R0 ← stack entry
≠BEQ≡≥	035376	001404				BEQ 3$			;If 0, then end of stack (RF:  this wont work!!)
≠JSR≡≡PC≡≡MARKQ≡≥	035400	004767	777662			JSR PC,MARKQ		;
≠MOV≡≡R0≡≡R3≡≥	035404	010013				MOV R0,(R3)		;Put it back (compacting may move it)
≠BR≡≥	035406	000772				BR 2$		;
≥					
≥						;Mark the old & new values used by changers
≠MOV≡≡OLDV≡≡R2≡≡R0≡≥	035410	016200	000022		3$:	MOV OLDV(R2),R0
≠JSR≡≡PC≡≡MARKQ≡≥	035414	004767	777646			JSR PC,MARKQ		;
≠MOV≡≡R0≡≡OLDV≡≡R2≡≥	035420	010062	000022			MOV R0,OLDV(R2)
≠MOV≡≡NEWV≡≡R2≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 84
	INTERP PAL[HAL,HE]	PAGE 3.1 	Interpreter	;Data structures

≥	035424	016200	000024			MOV NEWV(R2),R0
≠JSR≡≡PC≡≡MARKQ≡≥	035430	004767	777632			JSR PC,MARKQ		;
≠MOV≡≡R0≡≡NEWV≡≡R2≡≥	035434	010062	000024			MOV R0,NEWV(R2)
≥					
≥						;mark the environments
≠MOV≡≡ENV≡≡R2≡≡R0≡≥	035440	016200	000006			MOV ENV(R2),R0		;R0 ← environment
≠JSR≡≡PC≡≡MARKQ≡≥	035444	004767	777616			JSR PC,MARKQ		;
≠MOV≡≡R0≡≡ENV≡≡R2≡≥	035450	010062	000006			MOV R0,ENV(R2)		;
≠MOV≡≡R0≡≡R3≡≥	035454	010003			4$:	MOV R0,R3		;
≠MOV≡≡SLINK≡≡R3≡≡R0≡≥	035456	016300	000000			MOV SLINK(R3),R0	;R0 ← next environment
≠BEQ≡≥	035462	001405				BEQ 5$			;if any
≠JSR≡≡PC≡≡MARKQ≡≥	035464	004767	777576			JSR PC,MARKQ		;
≠MOV≡≡R0≡≡SLINK≡≡R3≡≥	035470	010063	000000			MOV R0,SLINK(R3)	;
≠BR≡≥	035474	000767				BR 4$
≥						
≠MOV≡≡NXTINT≡≡R2≡≡R2≡≥	035476	016202	000002		5$:	MOV NXTINT(R2),R2	;R2 ← LOC[next interpreter status block]
≠BNE≡≥	035502	001330				BNE 1$			;Repeat as necessary
≠MOV≡≡SP≡≡R3≡≥	035504	012603			6$:	MOV (SP)+,R3		;Restore R3
≠MOV≡≡SP≡≡R2≡≥	035506	012602				MOV (SP)+,R2		;Restore R2
≤EVSIG≡≥						EVSIG INTEVT		;
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	035510	016746	777574			      MOV INTEVT,-(SP)
≥	035514	104012				104012
≠RTS≡≡RF≡≥	035516	000205				RTS RF			;Return
≥					
≥					NEWENV:	;Gets a new environment, returns address in R0.
≠.IFNZ≡≡SMALLB≡≥		000001			    .IFNZ SMALLB
≠MOV≡≡ENVSPC≡≡R0≡≥	035520	012700	035050			MOV #ENVSPC,R0	;
≠JMP≡≡GETSBK≡≥	035524	000167	775726			JMP GETSBK	;Allocate from small blocks
≥					    .IFF
≥						MOV #ENVSIZ,R0	;
≥						JMP GTFREE	;Allocate from large blocks
≥					    .ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 85
	INTERP PAL[HAL,HE]	PAGE 4 	Interpreter	;Data structures

≥					;Interpreter itself: INTERP
≥					
≠.MACRO≡≤MAKEOP≠≥						.MACRO MAKEOP CNAME, ANAME	;Compiler name, Address name
≥						XX	CNAME
≥						ANAME
≥						.ENDM
≥					
≥					;The interpreter operation table
≤MAKEOP≡≥					INTOPS: MAKEOP XINVALID,INVALID		;Illegal instruction
≤XX≡≥						XX	XINVALID
≠.IFDF≡≡XINVAL≡≥						   .IFDF XINVALID
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XINVALID in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XINVAL≠≥		000012				    XINVALID == II
≡II≡≡II≠≥		000014				    II == II+2
≡INVALI≡≡INVALI≡≥	035530	036062				INVALID
≠.INSRT≡≥						.INSRT	INTOPS.PAL[HAL,HE]
≠COMMEN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 86
	INTOPS PAL[HAL,HE]	PAGE 1 	Interpreter	;Data structures

≥				COMMENT ⊗   VALID 00002 PAGES
≥				C REC  PAGE   DESCRIPTION
≥				C00001 00001
≥				C00002 00002	.SBTTL	Table of interpreter instructions
≥				C00012 ENDMK
≥					C⊗;
≠.SBTTL≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 87
	INTOPS PAL[HAL,HE]	PAGE 2 	Table of interpreter instructions

≥					.SBTTL	Table of interpreter instructions
≥					
≠COMMEN≡≥				COMMENT  ⊗
≥				This table is parallel to the file INTDEF.SAI[HAL,HE].  It is required
≥				at several places in the interpreter; each of these can define the
≥				macro MAKEOP however desired.  The convention here for types of
≥				arguments that each pseudo-op takes is this:
≥					a	absolute address
≥					la	list of absolute addresses
≥					o	offset or level-offset pair
≥					lo	list of offsets or level-offset pairs
≥					n	small constant
≥					r50	word of radix 50
≥					⊗
≥					
≡PCVERS≠≥		000005			PCVERSION == 5		;Fix this every time you add some new pcodes
≥					
≡II≠≥		000002				II == 2		;Start of interpreter jump table (0 is illegal instruction)
≥					
≥						;Motion control
≤MAKEOP≡≥					MAKEOP	XMOVE,MOVE,<a>	;Prepare, execute move whose traj table is at a.
≤XX≡≥						XX	XMOVE
≠.IFDF≡≡XMOVE≡≥						   .IFDF XMOVE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XMOVE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XMOVE≠≥		000002				    XMOVE == II
≡II≡≡II≠≥		000004				    II == II+2
≡MOVE≡≡MOVE≡≥	035532	045036				MOVE
≤MAKEOP≡≥					MAKEOP	XCENTER,CENTER,<a>,	;Center using traj table at a.
≤XX≡≥						XX	XCENTER
≠.IFDF≡≡XCENTE≡≥						   .IFDF XCENTER
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCENTER in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XCENTE≠≥		000004				    XCENTER == II
≡II≡≡II≠≥		000006				    II == II+2
≡CENTER≡≡CENTER≡≥	035534	045046				CENTER
≤MAKEOP≡≥					MAKEOP	XSTOP,STOP,<n>	;Cause all mechanisms whose bits are on in n to stop.
≤XX≡≥						XX	XSTOP
≠.IFDF≡≡XSTOP≡≥						   .IFDF XSTOP
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSTOP in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSTOP≠≥		000006				    XSTOP == II
≡II≡≡II≠≥		000010				    II == II+2
≡STOP≡≡STOP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 88
	INTOPS PAL[HAL,HE]	PAGE 2.1 	Table of interpreter instructions

≥	035536	045402				STOP
≤MAKEOP≡≥					MAKEOP	XNOTICE,NOTICE	;Make sure everyone knows where the arm is.
≤XX≡≥						XX	XNOTICE
≠.IFDF≡≡XNOTIC≡≥						   .IFDF XNOTICE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XNOTICE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XNOTIC≠≥		000010				    XNOTICE == II
≡II≡≡II≠≥		000012				    II == II+2
≡NOTICE≡≡NOTICE≡≥	035540	045540				NOTICE
≥					
≥						;Variables
≤MAKEOP≡≥					MAKEOP	XMVAR,MVAR,<lo>	;Make graph node for given offsets (list arg)
≤XX≡≥						XX	XMVAR
≠.IFDF≡≡XMVAR≡≥						   .IFDF XMVAR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XMVAR in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XMVAR≠≥		000012				    XMVAR == II
≡II≡≡II≠≥		000014				    II == II+2
≡MVAR≡≡MVAR≡≥	035542	036512				MVAR
≤MAKEOP≡≥					MAKEOP	XKVAR,KVAR,<lo>	;Kill graph node at given offsets (list arg)
≤XX≡≥						XX	XKVAR
≠.IFDF≡≡XKVAR≡≥						   .IFDF XKVAR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XKVAR in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XKVAR≠≥		000014				    XKVAR == II
≡II≡≡II≠≥		000016				    II == II+2
≡KVAR≡≡KVAR≡≥	035544	036562				KVAR
≤MAKEOP≡≥					MAKEOP	XGLBLNK,GLBLNK,<lo,r50,r50>
≤XX≡≥						XX	XGLBLNK
≠.IFDF≡≡XGLBLN≡≥						   .IFDF XGLBLNK
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XGLBLNK in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XGLBLN≠≥		000016				    XGLBLNK == II
≡II≡≡II≠≥		000020				    II == II+2
≡GLBLNK≡≡GLBLNK≡≥	035546	037424				GLBLNK
≥								;Link global given by r50,r50 into level-offset lo.
≤MAKEOP≡≥					MAKEOP	XMAKEVT,MAKEVT,<lo>	;Make event variables with offsets as in list.
≤XX≡≥						XX	XMAKEVT
≠.IFDF≡≡XMAKEV≡≥						   .IFDF XMAKEVT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XMAKEVT in two ways!!!
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 89
	INTOPS PAL[HAL,HE]	PAGE 2.2 	Table of interpreter instructions

≥						       .ENDC
≥						   .ENDC
≡II≡≡XMAKEV≠≥		000020				    XMAKEVT == II
≡II≡≡II≠≥		000022				    II == II+2
≡MAKEVT≡≡MAKEVT≡≥	035550	047776				MAKEVT
≤MAKEOP≡≥					MAKEOP	XDESEVT,DESEVT,<lo>	;Kill event variables with offsets as in list.
≤XX≡≥						XX	XDESEVT
≠.IFDF≡≡XDESEV≡≥						   .IFDF XDESEVT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XDESEVT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XDESEV≠≥		000022				    XDESEVT == II
≡II≡≡II≠≥		000024				    II == II+2
≡DESEVT≡≡DESEVT≡≥	035552	050122				DESEVT
≤MAKEOP≡≥					MAKEOP	XMEXP,MEXP,<lo,a,o>	;Make an expression whose needed list is lo
≤XX≡≥						XX	XMEXP
≠.IFDF≡≡XMEXP≡≥						   .IFDF XMEXP
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XMEXP in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XMEXP≠≥		000024				    XMEXP == II
≡II≡≡II≠≥		000026				    II == II+2
≡MEXP≡≡MEXP≡≥	035554	041070				MEXP
≥								; at address a, and call it offset o.
≤MAKEOP≡≥					MAKEOP	XMCLC,MCLC,<o,o>;Make the expression at level-offset o1 a calculator
≤XX≡≥						XX	XMCLC
≠.IFDF≡≡XMCLC≡≥						   .IFDF XMCLC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XMCLC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XMCLC≠≥		000026				    XMCLC == II
≡II≡≡II≠≥		000030				    II == II+2
≡MCLC≡≡MCLC≡≥	035556	041244				MCLC
≥								; for the variable at o2.
≤MAKEOP≡≥					MAKEOP	XDCLC,DCLC,<o,o>;Unmake the expression at level-offset o1 a calculator
≤XX≡≥						XX	XDCLC
≠.IFDF≡≡XDCLC≡≥						   .IFDF XDCLC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XDCLC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XDCLC≠≥		000030				    XDCLC == II
≡II≡≡II≠≥		000032				    II == II+2
≡DCLC≡≡DCLC≡≥	035560	041324				DCLC
≥								; for the variable at o2.
≤MAKEOP≡≥					MAKEOP	XMCHG,MCHG,<o,a>;Make a changer for variable at level-offset o at address a.
≤XX≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 90
	INTOPS PAL[HAL,HE]	PAGE 2.3 	Table of interpreter instructions

≥						XX	XMCHG
≠.IFDF≡≡XMCHG≡≥						   .IFDF XMCHG
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XMCHG in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XMCHG≠≥		000032				    XMCHG == II
≡II≡≡II≠≥		000034				    II == II+2
≡MCHG≡≡MCHG≡≥	035562	041414				MCHG
≤MAKEOP≡≥					MAKEOP	XGTOLD,GTOLD	;Get the old value for current changer.
≤XX≡≥						XX	XGTOLD
≠.IFDF≡≡XGTOLD≡≥						   .IFDF XGTOLD
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XGTOLD in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XGTOLD≠≥		000034				    XGTOLD == II
≡II≡≡II≠≥		000036				    II == II+2
≡GTOLD≡≡GTOLD≡≥	035564	041520				GTOLD
≤MAKEOP≡≥					MAKEOP	XGTNEW,GTNEW	;Get the new value for current changer.
≤XX≡≥						XX	XGTNEW
≠.IFDF≡≡XGTNEW≡≥						   .IFDF XGTNEW
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XGTNEW in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XGTNEW≠≥		000036				    XGTNEW == II
≡II≡≡II≠≥		000040				    II == II+2
≡GTNEW≡≡GTNEW≡≥	035566	041526				GTNEW
≥					
≥						;Stack operations
≤MAKEOP≡≥					MAKEOP	XGTVAL,GTVAL,<o>;Push value of arg (level-offset pair).
≤XX≡≥						XX	XGTVAL
≠.IFDF≡≡XGTVAL≡≥						   .IFDF XGTVAL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XGTVAL in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XGTVAL≠≥		000040				    XGTVAL == II
≡II≡≡II≠≥		000042				    II == II+2
≡GTVAL≡≡GTVAL≡≥	035570	036630				GTVAL
≤MAKEOP≡≥					MAKEOP	XIGTVAL,IGTVAL,<a>	;Push arg (immediate).
≤XX≡≥						XX	XIGTVAL
≠.IFDF≡≡XIGTVA≡≥						   .IFDF XIGTVAL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XIGTVAL in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XIGTVA≠≥		000042				    XIGTVAL == II
≡II≡≡II≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 91
	INTOPS PAL[HAL,HE]	PAGE 2.4 	Table of interpreter instructions

≥		000044				    II == II+2
≡IGTVAL≡≡IGTVAL≡≥	035572	037060				IGTVAL
≤MAKEOP≡≥					MAKEOP  XCHNGE,CHNGE,<o>;Pop value into arg (level-offset pair).
≤XX≡≥						XX	XCHNGE
≠.IFDF≡≡XCHNGE≡≥						   .IFDF XCHNGE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCHNGE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XCHNGE≠≥		000044				    XCHNGE == II
≡II≡≡II≠≥		000046				    II == II+2
≡CHNGE≡≡CHNGE≡≥	035574	037124				CHNGE
≤MAKEOP≡≥					MAKEOP  XICHNGE,ICHNGE,<a>;Pop value into arg (immediate).
≤XX≡≥						XX	XICHNGE
≠.IFDF≡≡XICHNG≡≥						   .IFDF XICHNGE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XICHNGE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XICHNG≠≥		000046				    XICHNGE == II
≡II≡≡II≠≥		000050				    II == II+2
≡ICHNGE≡≡ICHNGE≡≥	035576	037270				ICHNGE
≤MAKEOP≡≥					MAKEOP	XPUSH, PUSH,<a>	;Push arg directly (as a ptr) onto stack. For cnstnts.
≤XX≡≥						XX	XPUSH
≠.IFDF≡≡XPUSH≡≥						   .IFDF XPUSH
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XPUSH in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XPUSH≠≥		000050				    XPUSH == II
≡II≡≡II≠≥		000052				    II == II+2
≡PUSH≡≡PUSH≡≥	035600	037336				 PUSH
≤MAKEOP≡≥					MAKEOP	XPOP,  POP	;Pop stack.
≤XX≡≥						XX	XPOP
≠.IFDF≡≡XPOP≡≥						   .IFDF XPOP
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XPOP in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XPOP≠≥		000052				    XPOP == II
≡II≡≡II≠≥		000054				    II == II+2
≡POP≡≡POP≡≥	035602	037332				  POP
≤MAKEOP≡≥					MAKEOP	XCOPY, COPY ,<n>;Copy n'th down to top of stack.
≤XX≡≥						XX	XCOPY
≠.IFDF≡≡XCOPY≡≥						   .IFDF XCOPY
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCOPY in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XCOPY≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 92
	INTOPS PAL[HAL,HE]	PAGE 2.5 	Table of interpreter instructions

≥		000054				    XCOPY == II
≡II≡≡II≠≥		000056				    II == II+2
≡COPY≡≡COPY≡≥	035604	037352				 COPY 
≤MAKEOP≡≥					MAKEOP	XREPLAC,REPLAC,<n>	;Replace n'th down with top (which pop)
≤XX≡≥						XX	XREPLAC
≠.IFDF≡≡XREPLA≡≥						   .IFDF XREPLAC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XREPLAC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XREPLA≠≥		000056				    XREPLAC == II
≡II≡≡II≠≥		000060				    II == II+2
≡REPLAC≡≡REPLAC≡≥	035606	037374				REPLAC
≤MAKEOP≡≥					MAKEOP	XFLUSH,FLUSH	;Flush the entire stack.
≤XX≡≥						XX	XFLUSH
≠.IFDF≡≡XFLUSH≡≥						   .IFDF XFLUSH
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XFLUSH in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XFLUSH≠≥		000060				    XFLUSH == II
≡II≡≡II≠≥		000062				    II == II+2
≡FLUSH≡≡FLUSH≡≥	035610	037416				FLUSH
≥					
≥						;Flow of control
≤MAKEOP≡≥					MAKEOP	XJUMP, JUMP, <a>	;Jump to address
≤XX≡≥						XX	XJUMP
≠.IFDF≡≡XJUMP≡≥						   .IFDF XJUMP
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XJUMP in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XJUMP≠≥		000062				    XJUMP == II
≡II≡≡II≠≥		000064				    II == II+2
≡JUMP≡≡JUMP≡≥	035612	040274				 JUMP
≤MAKEOP≡≥					MAKEOP	XJUMPC,JUMPC,<a>	;Jump to address if "true"
≤XX≡≥						XX	XJUMPC
≠.IFDF≡≡XJUMPC≡≥						   .IFDF XJUMPC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XJUMPC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XJUMPC≠≥		000064				    XJUMPC == II
≡II≡≡II≠≥		000066				    II == II+2
≡JUMPC≡≡JUMPC≡≥	035614	040304				JUMPC
≤MAKEOP≡≥					MAKEOP	XTERMINATE,TERMINATE	;Terminate this interpreter
≤XX≡≥						XX	XTERMINATE
≠.IFDF≡≡XTERMI≡≥						   .IFDF XTERMINATE
≠.IF1≡≥						       .IF1
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 93
	INTOPS PAL[HAL,HE]	PAGE 2.6 	Table of interpreter instructions

≥						       .ERROR You are using XTERMINATE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTERMI≠≥		000066				    XTERMINATE == II
≡II≡≡II≠≥		000070				    II == II+2
≡TERMIN≡≡TERMIN≡≥	035616	040766				TERMINATE
≤MAKEOP≡≥					MAKEOP	XENDCLC,ENDCLC		;Return from calculator cell
≤XX≡≥						XX	XENDCLC
≠.IFDF≡≡XENDCL≡≥						   .IFDF XENDCLC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XENDCLC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XENDCL≠≥		000070				    XENDCLC == II
≡II≡≡II≠≥		000072				    II == II+2
≡ENDCLC≡≡ENDCLC≡≥	035620	041404				ENDCLC
≤MAKEOP≡≥					MAKEOP  XPROC, PROC,<a,lo>	;Call a procedure at a, with arg list lo 
≤XX≡≥						XX	XPROC
≠.IFDF≡≡XPROC≡≥						   .IFDF XPROC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XPROC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XPROC≠≥		000072				    XPROC == II
≡II≡≡II≠≥		000074				    II == II+2
≡PROC≡≡PROC≡≥	035622	037746				 PROC
≤MAKEOP≡≥					MAKEOP	XRETURN,RETURN	;Return from procedure
≤XX≡≥						XX	XRETURN
≠.IFDF≡≡XRETUR≡≥						   .IFDF XRETURN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XRETURN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XRETUR≠≥		000074				    XRETURN == II
≡II≡≡II≠≥		000076				    II == II+2
≡RETURN≡≡RETURN≡≥	035624	040146				RETURN
≤MAKEOP≡≥					MAKEOP	XSPROUT,SPROUT;la	;Sprout interpreters at each arg, wait (list arg)
≤XX≡≥						XX	XSPROUT
≠.IFDF≡≡XSPROU≡≥						   .IFDF XSPROUT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSPROUT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSPROU≠≥		000076				    XSPROUT == II
≡II≡≡II≠≥		000100				    II == II+2
≡SPROUT≡≡SPROUT≡≥	035626	040562				SPROUT
≤MAKEOP≡≥					MAKEOP	XFORCHK,FORCHK,<a>	;Do a FOR-loop check, and fail to location d.
≤XX≡≥						XX	XFORCHK
≠.IFDF≡≡XFORCH≡≥						   .IFDF XFORCHK
≠.IF1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 94
	INTOPS PAL[HAL,HE]	PAGE 2.7 	Table of interpreter instructions

≥						       .IF1
≥						       .ERROR You are using XFORCHK in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XFORCH≠≥		000100				    XFORCHK == II
≡II≡≡II≠≥		000102				    II == II+2
≡FORCHK≡≡FORCHK≡≥	035630	040232				FORCHK
≤MAKEOP≡≥					MAKEOP	XSIGNAL,SIGNAL,<o>	;Signal event at level-offset o.
≤XX≡≥						XX	XSIGNAL
≠.IFDF≡≡XSIGNA≡≥						   .IFDF XSIGNAL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSIGNAL in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSIGNA≠≥		000102				    XSIGNAL == II
≡II≡≡II≠≥		000104				    II == II+2
≡SIGNAL≡≡SIGNAL≡≥	035632	050040				SIGNAL
≤MAKEOP≡≥					MAKEOP	XWAITE,WAITE,<o>	;Wait on event at level-offset o.
≤XX≡≥						XX	XWAITE
≠.IFDF≡≡XWAITE≡≥						   .IFDF XWAITE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XWAITE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XWAITE≠≥		000104				    XWAITE == II
≡II≡≡II≠≥		000106				    II == II+2
≡WAITE≡≡WAITE≡≥	035634	050064				WAITE
≤MAKEOP≡≥					MAKEOP	XPAUSE,PAUSE		;Pause in seconds (on stack)
≤XX≡≥						XX	XPAUSE
≠.IFDF≡≡XPAUSE≡≥						   .IFDF XPAUSE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XPAUSE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XPAUSE≠≥		000106				    XPAUSE == II
≡II≡≡II≠≥		000110				    II == II+2
≡PAUSE≡≡PAUSE≡≥	035636	050166				PAUSE
≤MAKEOP≡≥					MAKEOP	XABORT,ABORT		;Abort current motions
≤XX≡≥						XX	XABORT
≠.IFDF≡≡XABORT≡≥						   .IFDF XABORT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XABORT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XABORT≠≥		000110				    XABORT == II
≡II≡≡II≠≥		000112				    II == II+2
≡ABORT≡≡ABORT≡≥	035640	040202				ABORT
≤MAKEOP≡≥					MAKEOP	XDDT,GODDT		;go to DDT.
≤XX≡≥						XX	XDDT
≠.IFDF≡≡XDDT≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 95
	INTOPS PAL[HAL,HE]	PAGE 2.8 	Table of interpreter instructions

≥						   .IFDF XDDT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XDDT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XDDT≠≥		000112				    XDDT == II
≡II≡≡II≠≥		000114				    II == II+2
≡GODDT≡≡GODDT≡≥	035642	040226				GODDT
≥					
≥						;Boolean
≤MAKEOP≡≥					MAKEOP	XSLE,SLE	;S≤S  compare top two elts, pop, pop, push answer
≤XX≡≥						XX	XSLE
≠.IFDF≡≡XSLE≡≥						   .IFDF XSLE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSLE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSLE≠≥		000114				    XSLE == II
≡II≡≡II≠≥		000116				    II == II+2
≡SLE≡≡SLE≡≥	035644	041602				SLE
≤MAKEOP≡≥					MAKEOP	XSLT,SLT	;S<S		true := 1.0
≤XX≡≥						XX	XSLT
≠.IFDF≡≡XSLT≡≥						   .IFDF XSLT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSLT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSLT≠≥		000116				    XSLT == II
≡II≡≡II≠≥		000120				    II == II+2
≡SLT≡≡SLT≡≥	035646	041566				SLT
≤MAKEOP≡≥					MAKEOP	XSGE,SGE	;S≥S		false:=  0
≤XX≡≥						XX	XSGE
≠.IFDF≡≡XSGE≡≥						   .IFDF XSGE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSGE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSGE≠≥		000120				    XSGE == II
≡II≡≡II≠≥		000122				    II == II+2
≡SGE≡≡SGE≡≥	035650	041632				SGE
≤MAKEOP≡≥					MAKEOP	XSGT,SGT	;S>S
≤XX≡≥						XX	XSGT
≠.IFDF≡≡XSGT≡≥						   .IFDF XSGT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSGT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSGT≠≥		000122				    XSGT == II
≡II≡≡II≠≥		000124				    II == II+2
≡SGT≡≡SGT≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 96
	INTOPS PAL[HAL,HE]	PAGE 2.9 	Table of interpreter instructions

≥	035652	041616				SGT
≤MAKEOP≡≥					MAKEOP	XSEQ,SEQ	;S=S
≤XX≡≥						XX	XSEQ
≠.IFDF≡≡XSEQ≡≥						   .IFDF XSEQ
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSEQ in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSEQ≠≥		000124				    XSEQ == II
≡II≡≡II≠≥		000126				    II == II+2
≡SEQ≡≡SEQ≡≥	035654	041646				SEQ
≤MAKEOP≡≥					MAKEOP	XSNE,SNE	;S≠S
≤XX≡≥						XX	XSNE
≠.IFDF≡≡XSNE≡≥						   .IFDF XSNE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSNE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSNE≠≥		000126				    XSNE == II
≡II≡≡II≠≥		000130				    II == II+2
≡SNE≡≡SNE≡≥	035656	041662				SNE
≤MAKEOP≡≥					MAKEOP	XAND,AND	;S∧S  (logical and)
≤XX≡≥						XX	XAND
≠.IFDF≡≡XAND≡≥						   .IFDF XAND
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XAND in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XAND≠≥		000130				    XAND == II
≡II≡≡II≠≥		000132				    II == II+2
≡AND≡≡AND≡≥	035660	041676				AND
≤MAKEOP≡≥					MAKEOP	XLOR,LOR		;S∨S  (logical or)
≤XX≡≥						XX	XLOR
≠.IFDF≡≡XLOR≡≥						   .IFDF XLOR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XLOR in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XLOR≠≥		000132				    XLOR == II
≡II≡≡II≠≥		000134				    II == II+2
≡LOR≡≡LOR≡≥	035662	041744				LOR
≤MAKEOP≡≥					MAKEOP	XNOT,NOT	;¬S   (logical not) note: this only takes one arg
≤XX≡≥						XX	XNOT
≠.IFDF≡≡XNOT≡≥						   .IFDF XNOT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XNOT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XNOT≠≥		000134				    XNOT == II
≡II≡≡II≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 97
	INTOPS PAL[HAL,HE]	PAGE 2.10 	Table of interpreter instructions

≥		000136				    II == II+2
≡NOT≡≡NOT≡≥	035664	042012				NOT
≥					
≥						;Arithmetic
≤MAKEOP≡≥					MAKEOP	XWHERE,WHERE,<n>	;Push the current location of mechanism n
≤XX≡≥						XX	XWHERE
≠.IFDF≡≡XWHERE≡≥						   .IFDF XWHERE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XWHERE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XWHERE≠≥		000136				    XWHERE == II
≡II≡≡II≠≥		000140				    II == II+2
≡WHERE≡≡WHERE≡≥	035666	045464				WHERE
≤MAKEOP≡≥					MAKEOP	XSADD, SADD	;S+S:  Add top two elts, pop, pop, push answer
≤XX≡≥						XX	XSADD
≠.IFDF≡≡XSADD≡≥						   .IFDF XSADD
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSADD in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSADD≠≥		000140				    XSADD == II
≡II≡≡II≠≥		000142				    II == II+2
≡SADD≡≡SADD≡≥	035670	042050				 SADD
≤MAKEOP≡≥					MAKEOP	XSSUB, SSUB	;S-S:  Sub top two elts, pop, pop, push answer
≤XX≡≥						XX	XSSUB
≠.IFDF≡≡XSSUB≡≥						   .IFDF XSSUB
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSSUB in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSSUB≠≥		000142				    XSSUB == II
≡II≡≡II≠≥		000144				    II == II+2
≡SSUB≡≡SSUB≡≥	035672	042066				 SSUB
≤MAKEOP≡≥					MAKEOP	XSNEG, SNEG	;-S:   Negate top elt, pop, push answer
≤XX≡≥						XX	XSNEG
≠.IFDF≡≡XSNEG≡≥						   .IFDF XSNEG
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSNEG in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSNEG≠≥		000144				    XSNEG == II
≡II≡≡II≠≥		000146				    II == II+2
≡SNEG≡≡SNEG≡≥	035674	042146				 SNEG
≤MAKEOP≡≥					MAKEOP	XSMUL, SMUL	;S*S:  Mul top two elts, pop, pop, push answer
≤XX≡≥						XX	XSMUL
≠.IFDF≡≡XSMUL≡≥						   .IFDF XSMUL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSMUL in two ways!!!
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 98
	INTOPS PAL[HAL,HE]	PAGE 2.11 	Table of interpreter instructions

≥						       .ENDC
≥						   .ENDC
≡II≡≡XSMUL≠≥		000146				    XSMUL == II
≡II≡≡II≠≥		000150				    II == II+2
≡SMUL≡≡SMUL≡≥	035676	042110				 SMUL
≤MAKEOP≡≥					MAKEOP	XSDIV, SDIV	;S/S:  Div top two elts, pop, pop, push answer
≤XX≡≥						XX	XSDIV
≠.IFDF≡≡XSDIV≡≥						   .IFDF XSDIV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSDIV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSDIV≠≥		000150				    XSDIV == II
≡II≡≡II≠≥		000152				    II == II+2
≡SDIV≡≡SDIV≡≥	035700	042126				 SDIV
≤MAKEOP≡≥					MAKEOP	XVMAGN, VMAGN	;S ← norm of vector
≤XX≡≥						XX	XVMAGN
≠.IFDF≡≡XVMAGN≡≥						   .IFDF XVMAGN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XVMAGN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XVMAGN≠≥		000152				    XVMAGN == II
≡II≡≡II≠≥		000154				    II == II+2
≡VMAGN≡≡VMAGN≡≥	035702	042310				 VMAGN
≤MAKEOP≡≥					MAKEOP	XVDOT, VDOT	;S ← vector dot vector
≤XX≡≥						XX	XVDOT
≠.IFDF≡≡XVDOT≡≥						   .IFDF XVDOT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XVDOT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XVDOT≠≥		000154				    XVDOT == II
≡II≡≡II≠≥		000156				    II == II+2
≡VDOT≡≡VDOT≡≥	035704	042164				 VDOT
≤MAKEOP≡≥					MAKEOP	XPVDOT,PVDOT	;S ← vector dot vector all 4 cells
≤XX≡≥						XX	XPVDOT
≠.IFDF≡≡XPVDOT≡≥						   .IFDF XPVDOT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XPVDOT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XPVDOT≠≥		000156				    XPVDOT == II
≡II≡≡II≠≥		000160				    II == II+2
≡PVDOT≡≡PVDOT≡≥	035706	042240				PVDOT
≤MAKEOP≡≥					MAKEOP	XSSBRTN,SSBRTN,<n>	;S ← SBRTN[n](top scalar elt)
≤XX≡≥						XX	XSSBRTN
≠.IFDF≡≡XSSBRT≡≥						   .IFDF XSSBRTN
≠.IF1≡≥						       .IF1
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 99
	INTOPS PAL[HAL,HE]	PAGE 2.12 	Table of interpreter instructions

≥						       .ERROR You are using XSSBRTN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSSBRT≠≥		000160				    XSSBRTN == II
≡II≡≡II≠≥		000162				    II == II+2
≡SSBRTN≡≡SSBRTN≡≥	035710	042364				SSBRTN
≤MAKEOP≡≥					MAKEOP	XTMAGN,TMAGN	;S ← extracts angle of rotation from trans
≤XX≡≥						XX	XTMAGN
≠.IFDF≡≡XTMAGN≡≥						   .IFDF XTMAGN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTMAGN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTMAGN≠≥		000162				    XTMAGN == II
≡II≡≡II≠≥		000164				    II == II+2
≡TMAGN≡≡TMAGN≡≥	035712	042764				TMAGN
≤MAKEOP≡≥					MAKEOP	XTAXIS,TAXIS	;V ← extracts axis of rotation from trans
≤XX≡≥						XX	XTAXIS
≠.IFDF≡≡XTAXIS≡≥						   .IFDF XTAXIS
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTAXIS in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTAXIS≠≥		000164				    XTAXIS == II
≡II≡≡II≠≥		000166				    II == II+2
≡TAXIS≡≡TAXIS≡≥	035714	042724				TAXIS
≤MAKEOP≡≥					MAKEOP	XVMAKE,VMAKE	;V ← vector(scalar,scalar,scalar)
≤XX≡≥						XX	XVMAKE
≠.IFDF≡≡XVMAKE≡≥						   .IFDF XVMAKE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XVMAKE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XVMAKE≠≥		000166				    XVMAKE == II
≡II≡≡II≠≥		000170				    II == II+2
≡VMAKE≡≡VMAKE≡≥	035716	043560				VMAKE
≤MAKEOP≡≥					MAKEOP	XSVMUL,SVMUL	;V ← scalar * vector
≤XX≡≥						XX	XSVMUL
≠.IFDF≡≡XSVMUL≡≥						   .IFDF XSVMUL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XSVMUL in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XSVMUL≠≥		000170				    XSVMUL == II
≡II≡≡II≠≥		000172				    II == II+2
≡SVMUL≡≡SVMUL≡≥	035720	043504				SVMUL
≤MAKEOP≡≥					MAKEOP	XVADD, VADD	;V ← vector + vector
≤XX≡≥						XX	XVADD
≠.IFDF≡≡XVADD≡≥						   .IFDF XVADD
≠.IF1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 100
	INTOPS PAL[HAL,HE]	PAGE 2.13 	Table of interpreter instructions

≥						       .IF1
≥						       .ERROR You are using XVADD in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XVADD≠≥		000172				    XVADD == II
≡II≡≡II≠≥		000174				    II == II+2
≡VADD≡≡VADD≡≥	035722	043620				 VADD
≤MAKEOP≡≥					MAKEOP	XVSUB, VSUB	;V ← vector - vector
≤XX≡≥						XX	XVSUB
≠.IFDF≡≡XVSUB≡≥						   .IFDF XVSUB
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XVSUB in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XVSUB≠≥		000174				    XVSUB == II
≡II≡≡II≠≥		000176				    II == II+2
≡VSUB≡≡VSUB≡≥	035724	043672				 VSUB
≤MAKEOP≡≥					MAKEOP	XUNITV,UNITV  	;Vector ← vector / its norm
≤XX≡≥						XX	XUNITV
≠.IFDF≡≡XUNITV≡≥						   .IFDF XUNITV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XUNITV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XUNITV≠≥		000176				    XUNITV == II
≡II≡≡II≠≥		000200				    II == II+2
≡UNITV≡≡UNITV≡≥	035726	042476				UNITV
≥						;CROSV remove	;Vector ← vector cross vector
≤MAKEOP≡≥					MAKEOP	XTVMUL,TVMUL	;Vector ← trans * vector
≤XX≡≥						XX	XTVMUL
≠.IFDF≡≡XTVMUL≡≥						   .IFDF XTVMUL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTVMUL in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTVMUL≠≥		000200				    XTVMUL == II
≡II≡≡II≠≥		000202				    II == II+2
≡TVMUL≡≡TVMUL≡≥	035730	043720				TVMUL
≤MAKEOP≡≥					MAKEOP	XTPOS,TPOS	;Vector ← translation_part_of_trans
≤XX≡≥						XX	XTPOS
≠.IFDF≡≡XTPOS≡≥						   .IFDF XTPOS
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTPOS in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTPOS≠≥		000202				    XTPOS == II
≡II≡≡II≠≥		000204				    II == II+2
≡TPOS≡≡TPOS≡≥	035732	042572				TPOS
≤MAKEOP≡≥					MAKEOP	XTORIEN,TORIEN	;T ← rotation_part_of_trans
≤XX≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 101
	INTOPS PAL[HAL,HE]	PAGE 2.14 	Table of interpreter instructions

≥						XX	XTORIEN
≠.IFDF≡≡XTORIE≡≥						   .IFDF XTORIEN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTORIEN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTORIE≠≥		000204				    XTORIEN == II
≡II≡≡II≠≥		000206				    II == II+2
≡TORIEN≡≡TORIEN≡≥	035734	042640				TORIEN
≤MAKEOP≡≥					MAKEOP	XVSAXWR,VSAXWR	;T ← rotation(vector,angle)
≤XX≡≥						XX	XVSAXWR
≠.IFDF≡≡XVSAXW≡≥						   .IFDF XVSAXWR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XVSAXWR in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XVSAXW≠≥		000206				    XVSAXWR == II
≡II≡≡II≠≥		000210				    II == II+2
≡VSAXWR≡≡VSAXWR≡≥	035736	044550				VSAXWR
≤MAKEOP≡≥					MAKEOP	XTMAKE,TMAKE	;T ← trans(rot,vector)
≤XX≡≥						XX	XTMAKE
≠.IFDF≡≡XTMAKE≡≥						   .IFDF XTMAKE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTMAKE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTMAKE≠≥		000210				    XTMAKE == II
≡II≡≡II≠≥		000212				    II == II+2
≡TMAKE≡≡TMAKE≡≥	035740	044030				TMAKE
≤MAKEOP≡≥					MAKEOP	XTVADD,TVADD	;T ← t + v
≤XX≡≥						XX	XTVADD
≠.IFDF≡≡XTVADD≡≥						   .IFDF XTVADD
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTVADD in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTVADD≠≥		000212				    XTVADD == II
≡II≡≡II≠≥		000214				    II == II+2
≡TVADD≡≡TVADD≡≥	035742	044150				TVADD
≤MAKEOP≡≥					MAKEOP	XTVSUB,TVSUB	;T ← t - v
≤XX≡≥						XX	XTVSUB
≠.IFDF≡≡XTVSUB≡≥						   .IFDF XTVSUB
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTVSUB in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTVSUB≠≥		000214				    XTVSUB == II
≡II≡≡II≠≥		000216				    II == II+2
≡TVSUB≡≡TVSUB≡≥	035744	044206				TVSUB
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 102
	INTOPS PAL[HAL,HE]	PAGE 2.15 	Table of interpreter instructions

≥						;FTOF
≤MAKEOP≡≥					MAKEOP	XTTMUL,TTMUL	;T ← trans * trans
≤XX≡≥						XX	XTTMUL
≠.IFDF≡≡XTTMUL≡≥						   .IFDF XTTMUL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTTMUL in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTTMUL≠≥		000216				    XTTMUL == II
≡II≡≡II≠≥		000220				    II == II+2
≡TTMUL≡≡TTMUL≡≥	035746	044226				TTMUL
≤MAKEOP≡≥					MAKEOP	XTINVRT,TINVRT	;T ← trans * trans
≤XX≡≥						XX	XTINVRT
≠.IFDF≡≡XTINVR≡≥						   .IFDF XTINVRT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTINVRT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTINVR≠≥		000220				    XTINVRT == II
≡II≡≡II≠≥		000222				    II == II+2
≡TINVRT≡≡TINVRT≡≥	035750	044422				TINVRT
≥					
≥						;Condition monitors
≤MAKEOP≡≥					MAKEOP	XCMMAK,CMMAK,<o>;Make a c-m at offset o
≤XX≡≥						XX	XCMMAK
≠.IFDF≡≡XCMMAK≡≥						   .IFDF XCMMAK
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCMMAK in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XCMMAK≠≥		000222				    XCMMAK == II
≡II≡≡II≠≥		000224				    II == II+2
≡CMMAK≡≡CMMAK≡≥	035752	045650				CMMAK
≤MAKEOP≡≥					MAKEOP	XCMENBL,CMENBL,<o>	;Enable c-m at level-offset o
≤XX≡≥						XX	XCMENBL
≠.IFDF≡≡XCMENB≡≥						   .IFDF XCMENBL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCMENBL in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XCMENB≠≥		000224				    XCMENBL == II
≡II≡≡II≠≥		000226				    II == II+2
≡CMENBL≡≡CMENBL≡≥	035754	046212				CMENBL
≤MAKEOP≡≥					MAKEOP	XCMDSBL,CMDSBL,<o>	;Disable c-m at level-offset o
≤XX≡≥						XX	XCMDSBL
≠.IFDF≡≡XCMDSB≡≥						   .IFDF XCMDSBL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCMDSBL in two ways!!!
≥						       .ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 103
	INTOPS PAL[HAL,HE]	PAGE 2.16 	Table of interpreter instructions

≥						   .ENDC
≡II≡≡XCMDSB≠≥		000226				    XCMDSBL == II
≡II≡≡II≠≥		000230				    II == II+2
≡CMDSBL≡≡CMDSBL≡≥	035756	046252				CMDSBL
≤MAKEOP≡≥					MAKEOP	XCMDEST,CMDEST,<lo>	;Destroy c-m at offset lo (list arg)
≤XX≡≥						XX	XCMDEST
≠.IFDF≡≡XCMDES≡≥						   .IFDF XCMDEST
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCMDEST in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XCMDES≠≥		000230				    XCMDEST == II
≡II≡≡II≠≥		000232				    II == II+2
≡CMDEST≡≡CMDEST≡≥	035760	046316				CMDEST
≤MAKEOP≡≥					MAKEOP	XCMTRIG,CMTRIG	;Trigger the c-m body (use only in checker)
≤XX≡≥						XX	XCMTRIG
≠.IFDF≡≡XCMTRI≡≥						   .IFDF XCMTRIG
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCMTRIG in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XCMTRI≠≥		000232				    XCMTRIG == II
≡II≡≡II≠≥		000234				    II == II+2
≡CMTRIG≡≡CMTRIG≡≥	035762	046372				CMTRIG
≤MAKEOP≡≥					MAKEOP	XCMSKED,CMSKED,<n>	;Sleep for n mills (use only in checker)
≤XX≡≥						XX	XCMSKED
≠.IFDF≡≡XCMSKE≡≥						   .IFDF XCMSKED
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCMSKED in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XCMSKE≠≥		000234				    XCMSKED == II
≡II≡≡II≠≥		000236				    II == II+2
≡CMSKED≡≡CMSKED≡≥	035764	046436				CMSKED
≤MAKEOP≡≥					MAKEOP	XCMUNCR,CMUNCR	;Start uncritical section
≤XX≡≥						XX	XCMUNCR
≠.IFDF≡≡XCMUNC≡≥						   .IFDF XCMUNCR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XCMUNCR in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XCMUNC≠≥		000236				    XCMUNCR == II
≡II≡≡II≠≥		000240				    II == II+2
≡CMUNCR≡≡CMUNCR≡≥	035766	046570				CMUNCR
≥					
≥						;Force control
≤MAKEOP≡≥					MAKEOP	XGETFORCE,GETFORCE,<o>	;Push current force via FMBLK in <o>
≤XX≡≥						XX	XGETFORCE
≠.IFDF≡≡XGETFO≡≥						   .IFDF XGETFORCE
≠.IF1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 104
	INTOPS PAL[HAL,HE]	PAGE 2.17 	Table of interpreter instructions

≥						       .IF1
≥						       .ERROR You are using XGETFORCE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XGETFO≠≥		000240				    XGETFORCE == II
≡II≡≡II≠≥		000242				    II == II+2
≡GETFOR≡≡GETFOR≡≥	035770	047236				GETFORCE
≤MAKEOP≡≥					MAKEOP	XMAKFORCE,MAKFORCE,<o,n>;Make FMBLK in offset <o> for mechanism n
≤XX≡≥						XX	XMAKFORCE
≠.IFDF≡≡XMAKFO≡≥						   .IFDF XMAKFORCE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XMAKFORCE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XMAKFO≠≥		000242				    XMAKFORCE == II
≡II≡≡II≠≥		000244				    II == II+2
≡MAKFOR≡≡MAKFOR≡≥	035772	046730				MAKFORCE
≤MAKEOP≡≥					MAKEOP	XDESFORCE,DESFORCE,<o>	;Destroy FMBLK in level-offset <o>
≤XX≡≥						XX	XDESFORCE
≠.IFDF≡≡XDESFO≡≥						   .IFDF XDESFORCE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XDESFORCE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XDESFO≠≥		000244				    XDESFORCE == II
≡II≡≡II≠≥		000246				    II == II+2
≡DESFOR≡≡DESFOR≡≥	035774	047100				DESFORCE
≥					
≥						;Initialization
≤MAKEOP≡≥					MAKEOP	XPROG,PROG		;Initialize mechanism variables
≤XX≡≥						XX	XPROG
≠.IFDF≡≡XPROG≡≥						   .IFDF XPROG
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XPROG in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XPROG≠≥		000246				    XPROG == II
≡II≡≡II≠≥		000250				    II == II+2
≡PROG≡≡PROG≡≥	035776	051000				PROG
≤MAKEOP≡≥					MAKEOP	XENDP,ENDP		;Clean up mechanism variables
≤XX≡≥						XX	XENDP
≠.IFDF≡≡XENDP≡≥						   .IFDF XENDP
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XENDP in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XENDP≠≥		000250				    XENDP == II
≡II≡≡II≠≥		000252				    II == II+2
≡ENDP≡≡ENDP≡≥	036000	051126				ENDP
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 105
	INTOPS PAL[HAL,HE]	PAGE 2.18 	Table of interpreter instructions

≥					
≥						;Debugging aids
≤MAKEOP≡≥					MAKEOP	XPRINT,PRINT	;Type an ASCIZ string on the VT05.
≤XX≡≥						XX	XPRINT
≠.IFDF≡≡XPRINT≡≥						   .IFDF XPRINT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XPRINT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XPRINT≠≥		000252				    XPRINT == II
≡II≡≡II≠≥		000254				    II == II+2
≡PRINT≡≡PRINT≡≥	036002	050210				PRINT
≤MAKEOP≡≥					MAKEOP	XVALPRN,VALPRN	;Type a value, whatever type it is, and pop it.
≤XX≡≥						XX	XVALPRN
≠.IFDF≡≡XVALPR≡≥						   .IFDF XVALPRN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XVALPRN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XVALPR≠≥		000254				    XVALPRN == II
≡II≡≡II≠≥		000256				    II == II+2
≡VALPRN≡≡VALPRN≡≥	036004	050254				VALPRN
≤MAKEOP≡≥					MAKEOP	XVARPRN,VARPRN,<o>	;Type a variable (level-offset), whatever type.
≤XX≡≥						XX	XVARPRN
≠.IFDF≡≡XVARPR≡≥						   .IFDF XVARPRN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XVARPRN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XVARPR≠≥		000256				    XVARPRN == II
≡II≡≡II≠≥		000260				    II == II+2
≡VARPRN≡≡VARPRN≡≥	036006	050244				VARPRN
≤MAKEOP≡≥					MAKEOP	XBRACE,NOOP	;Bracepoint in the program (break or trace)
≤XX≡≥						XX	XBRACE
≠.IFDF≡≡XBRACE≡≥						   .IFDF XBRACE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XBRACE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XBRACE≠≥		000260				    XBRACE == II
≡II≡≡II≠≥		000262				    II == II+2
≡NOOP≡≡NOOP≡≥	036010	050760				NOOP
≤MAKEOP≡≥					MAKEOP	XNOOP,NOOP	;Null operation
≤XX≡≥						XX	XNOOP
≠.IFDF≡≡XNOOP≡≥						   .IFDF XNOOP
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XNOOP in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XNOOP≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 106
	INTOPS PAL[HAL,HE]	PAGE 2.19 	Table of interpreter instructions

≥		000262				    XNOOP == II
≡II≡≡II≠≥		000264				    II == II+2
≡NOOP≡≡NOOP≡≥	036012	050760				NOOP
≤MAKEOP≡≥					MAKEOP	XTOPAL,TOPAL	;Escape to PAL
≤XX≡≥						XX	XTOPAL
≠.IFDF≡≡XTOPAL≡≥						   .IFDF XTOPAL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using XTOPAL in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡XTOPAL≠≥		000264				    XTOPAL == II
≡II≡≡II≠≥		000266				    II == II+2
≡TOPAL≡≡TOPAL≡≥	036014	050762				TOPAL
≡II≡≡INSEND≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 107
	INTERP PAL[HAL,HE]	PAGE 4.1 	Table of interpreter instructions

≥		000266				INSEND = II	;Marks the end of the instructions
≥					
≠.MACRO≡≤BMPIPC≠≥						.MACRO BMPIPC	;
≥						ADD #2,IPC(R4)	;Bump IPC
≥						.ENDM		;
≥					
≠.MACRO≡≤BACKIP≠≥						.MACRO BACKIPC	;
≥						SUB #2,IPC(R4)	;Backup IPC
≥						.ENDM		;
≥					
≠.MACRO≡≤CCC≠≥						.MACRO CCC	;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≥						.ENDM
≥					
≠.MACRO≡≤SCC≠≥						.MACRO SCC	;Set condition code
≥					;	MOV #2,R0	;Set condition code.  Not used right now. (maybe use TST PC)
≥						.ENDM
≥					
≥					INTERP:
≠MOV≡≡R3≡≡R0≡≥	036016	010300				MOV R3,R0	;Save the limit of the interpreter stack for error checking.
≠SUB≡≡INSTSZ≡≡R0≡≥	036020	162700	000040			SUB #2*INSTSZ,R0	
≠MOV≡≡R0≡≡SP≡≥	036024	010046				MOV R0,-(SP)	;
≠CMP≡≡R3≡≡SP≡≥	036026	020316			INT1:	CMP R3,(SP)	;Interpreter stack overflow?
≠BGE≡≥	036030	002004				BGE 1$		;No.  Go to next instruction.
≤HALERR≡≥						HALERR INTMS3	;Yes.  Complain.
≠MOV≡≡INTMS3≡≡SP≡≥	036032	012746	036226			MOV #INTMS3,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	036036	004777	755750			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠CLR≡≡R3≡≥	036042	005063	777776		1$:	CLR -2(R3)	;Zero above top of stack - to keep MINTS happy
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	036046	017400	000000			MOV @IPC(R4),R0	;R0 ← next instruction
≠BLE≡≡INVALI≡≥	036052	003403				BLE INVALID	;Instruction out of range
≠CMP≡≡R0≡≡INSEND≡≥	036054	020027	000266			CMP R0,#INSEND	;Is instruction too large?
≠BLE≡≡INT2≡≥	036060	003404				BLE INT2	;No.
≤HALERR≡≥					INVALID:HALERR INTMS1	;Yes. complain.
≠MOV≡≡INTMS1≡≡SP≡≥	036062	012746	036106			MOV #INTMS1,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	036066	004777	755720			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤BMPIPC≡≥					INT2:	BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	036072	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡INTOPS≡≡R0≡≥	036100	004770	035530			JSR PC,@INTOPS(R0)	;Call the appropriate routine
≠BR≡≡INT1≡≥	036104	000750				BR INT1		;Repeat interpreter loop
≥					
≥					
≤ASCIE≡≥					INTMS1:	ASCIE /INTERPRETER INSTRUCTION OUT OF RANGE/
≠.ASCIZ≡≥	036106	   111		
≥	036107	   116		
≥	036110	   124		
≥	036111	   105		
≥	036112	   122		
≥	036113	   120		
≥	036114	   122		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 108
	INTERP PAL[HAL,HE]	PAGE 4.2 	Table of interpreter instructions

≥	036115	   105		
≥	036116	   124		
≥	036117	   105		
≥	036120	   122		
≥	036121	   040		
≥	036122	   111		
≥	036123	   116		
≥	036124	   123		
≥	036125	   124		
≥	036126	   122		
≥	036127	   125		
≥	036130	   103		
≥	036131	   124		
≥	036132	   111		
≥	036133	   117		
≥	036134	   116		
≥	036135	   040		
≥	036136	   117		
≥	036137	   125		
≥	036140	   124		
≥	036141	   040		
≥	036142	   117		
≥	036143	   106		
≥	036144	   040		
≥	036145	   122		
≥	036146	   101		
≥	036147	   116		
≥	036150	   107		
≥	036151	   105		
≥	036152	   000		
≥					       .ASCIZ /INTERPRETER INSTRUCTION OUT OF RANGE/
≠.EVEN≡≥		036154			       .EVEN
≤ASCIE≡≥					INTMS2:	ASCIE /INTERPRETED INSTRUCTION RETURNED FAILURE/
≠.ASCIZ≡≥	036154	   111		
≥	036155	   116		
≥	036156	   124		
≥	036157	   105		
≥	036160	   122		
≥	036161	   120		
≥	036162	   122		
≥	036163	   105		
≥	036164	   124		
≥	036165	   105		
≥	036166	   104		
≥	036167	   040		
≥	036170	   111		
≥	036171	   116		
≥	036172	   123		
≥	036173	   124		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 109
	INTERP PAL[HAL,HE]	PAGE 4.3 	Table of interpreter instructions

≥	036174	   122		
≥	036175	   125		
≥	036176	   103		
≥	036177	   124		
≥	036200	   111		
≥	036201	   117		
≥	036202	   116		
≥	036203	   040		
≥	036204	   122		
≥	036205	   105		
≥	036206	   124		
≥	036207	   125		
≥	036210	   122		
≥	036211	   116		
≥	036212	   105		
≥	036213	   104		
≥	036214	   040		
≥	036215	   106		
≥	036216	   101		
≥	036217	   111		
≥	036220	   114		
≥	036221	   125		
≥	036222	   122		
≥	036223	   105		
≥	036224	   000		
≥					       .ASCIZ /INTERPRETED INSTRUCTION RETURNED FAILURE/
≠.EVEN≡≥		036226			       .EVEN
≤ASCIE≡≥					INTMS3:	ASCIE /INTERPRETER STACK OVERFLOW/
≠.ASCIZ≡≥	036226	   111		
≥	036227	   116		
≥	036230	   124		
≥	036231	   105		
≥	036232	   122		
≥	036233	   120		
≥	036234	   122		
≥	036235	   105		
≥	036236	   124		
≥	036237	   105		
≥	036240	   122		
≥	036241	   040		
≥	036242	   123		
≥	036243	   124		
≥	036244	   101		
≥	036245	   103		
≥	036246	   113		
≥	036247	   040		
≥	036250	   117		
≥	036251	   126		
≥	036252	   105		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 110
	INTERP PAL[HAL,HE]	PAGE 4.4 	Table of interpreter instructions

≥	036253	   122		
≥	036254	   106		
≥	036255	   114		
≥	036256	   117		
≥	036257	   127		
≥	036260	   000		
≥					       .ASCIZ /INTERPRETER STACK OVERFLOW/
≠.EVEN≡≥		036262			       .EVEN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 111
	INTERP PAL[HAL,HE]	PAGE 5 	Table of interpreter instructions

≥					;  GETARG, GETSCA, GETVEC, GETTRN
≥					
≥					GETARG:
≠COMMEN≡≥				COMMENT ⊗
≥				 Arguments:  
≥				   R0=variable name:  high byte is lexical level, low byte is offset.
≥				   R4=pointer to interpreter status block.
≥				 Result:
≥				   R0← pointer to address of desired variable.  
≥				   R1 clobbered.
≥				 This routine returns in R0 a pointer to the location in the current
≥				   environment (or, if necessary, more global environment) which
≥					   points to the variable which is named in R0. ⊗
≠MOV≡≡R2≡≡SP≡≥	036262	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡R0≡≡R1≡≥	036264	010001				MOV R0,R1	;
≠BIC≡≡R1≡≥	036266	042701	177400			BIC #177400,R1	;R1 ← Offset desired
≠CLRB≡≡R0≡≥	036272	105000				CLRB R0		;
≠SWAB≡≡R0≡≥	036274	000300				SWAB R0		;R0 ← Lexical level
≠MOV≡≡ENV≡≡R4≡≡R2≡≥	036276	016402	000006			MOV ENV(R4),R2	;R2 ← LOC[local environment]
≠SUB≡≡LEV≡≡R4≡≡R0≡≥	036302	166400	000010			SUB LEV(R4),R0	;R0 ← Difference in levels: desired-got
≠BEQ≡≥	036306	001405				BEQ 2$		;Diff=0; can use R2 as pointer at right base.
≠BHI≡≥	036310	101010				BHI 3$		;If diff>0, then value inaccessible.
≠MOV≡≡SLINK≡≡R2≡≡R2≡≥	036312	016202	000000		1$:	MOV SLINK(R2),R2;Must go up a level.  R2 ← LOC[more global environment]
≠INC≡≡R0≡≥	036316	005200				INC R0		;R0 ← New difference in levels
≠BNE≡≥	036320	001374				BNE 1$		;If not yet good, then move up another level
≠ADD≡≡R2≡≡R1≡≥	036322	060201			2$:	ADD R2,R1	;R1 ← environment + offset = location of desired pointer
≠MOV≡≡SP≡≡R2≡≥	036324	012602				MOV (SP)+,R2	;Restore R2.
≠MOV≡≡R1≡≡R0≡≥	036326	010100				MOV R1,R0	;
≠RTS≡≡PC≡≥	036330	000207				RTS PC		;Done.
≤PUNT≡≥					3$:	PUNT GTMS1
≠MOV≡≡GTMS1≡≡SP≡≥	036332	012746	036354			MOV #GTMS1,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	036336	004777	755450			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠MOV≡≡PNTMES≡≡SP≡≥	036342	012746	064310			MOV #PNTMES,-(SP)	;Push the "Can't continue" message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	036346	004777	755440			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠BR≡≥	036352	000773				BR .-10			;Loop forever or until he gives up
≤ASCIE≡≥					GTMS1:	ASCIE /ATTEMPT TO ACCESS UNAVAILABLE VARIABLE/
≠.ASCIZ≡≥	036354	   101		
≥	036355	   124		
≥	036356	   124		
≥	036357	   105		
≥	036360	   115		
≥	036361	   120		
≥	036362	   124		
≥	036363	   040		
≥	036364	   124		
≥	036365	   117		
≥	036366	   040		
≥	036367	   101		
≥	036370	   103		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 112
	INTERP PAL[HAL,HE]	PAGE 5.1 	Table of interpreter instructions

≥	036371	   103		
≥	036372	   105		
≥	036373	   123		
≥	036374	   123		
≥	036375	   040		
≥	036376	   125		
≥	036377	   116		
≥	036400	   101		
≥	036401	   126		
≥	036402	   101		
≥	036403	   111		
≥	036404	   114		
≥	036405	   101		
≥	036406	   102		
≥	036407	   114		
≥	036410	   105		
≥	036411	   040		
≥	036412	   126		
≥	036413	   101		
≥	036414	   122		
≥	036415	   111		
≥	036416	   101		
≥	036417	   102		
≥	036420	   114		
≥	036421	   105		
≥	036422	   000		
≥					       .ASCIZ /ATTEMPT TO ACCESS UNAVAILABLE VARIABLE/
≠.EVEN≡≥		036424			       .EVEN
≥					
≥					GETSCA:	;Gets place for a scalar result, and places a pointer on
≥						;the interpreter stack.  Location is returned in R0.  
≥						;Simple procedure.
≠.IFNZ≡≡SMALLB≡≥		000001			    .IFNZ SMALLB
≠MOV≡≡SCASPC≡≡R0≡≥	036424	012700	034700			MOV #SCASPC,R0	;
≠JSR≡≡PC≡≡GETSBK≡≥	036430	004767	775022			JSR PC,GETSBK	;Allocate from small blocks
≠MOV≡≡R0≡≡R3≡≥	036434	010043			 	MOV R0,-(R3)	;Push new value cell pointer on interpreter stack.
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	036436	016746	773246			      MOV SBEVT,-(SP)
≥	036442	104012				104012
≥					    .IFF
≥						MOV #2,R0	;Number of words needed
≥						JSR PC,GTFREE	;R0 ← LOC[new block]
≥					 	MOV R0,-(R3)	;Push new value cell pointer on interpreter stack.
≥					    .ENDC
≠RTS≡≡PC≡≥	036444	000207				RTS PC		;Done
≥					
≥					GETVEC:	;Gets place for a vector result, and places a pointer on
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 113
	INTERP PAL[HAL,HE]	PAGE 5.2 	Table of interpreter instructions

≥						;the interpreter stack.  Location is returned in R0.  
≥						;Simple procedure.
≠.IFNZ≡≡SMALLB≡≥		000001			    .IFNZ SMALLB
≠MOV≡≡VCTSPC≡≡R0≡≥	036446	012700	034732			MOV #VCTSPC,R0	;
≠JSR≡≡PC≡≡GETSBK≡≥	036452	004767	775000			JSR PC,GETSBK	;Allocate from small blocks
≠MOV≡≡R0≡≡R3≡≥	036456	010043			 	MOV R0,-(R3)	;Push new value cell pointer on interpreter stack.
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	036460	016746	773224			      MOV SBEVT,-(SP)
≥	036464	104012				104012
≥					    .IFF
≥					 	MOV #10,R0	;Number of words needed
≥					 	JSR PC,GTFREE	;R0 ← LOC[new block]
≥						MOV R0,-(R3)	;Push new value cell pointer on interpreter stack.
≥					    .ENDC
≠RTS≡≡PC≡≥	036466	000207				RTS PC		;Done
≥					
≥					GETTRN:	;Gets place for a trans result, and places a pointer on
≥						;the interpreter stack.  Location is returned in R0.  
≥						;Simple procedure.
≠.IFNZ≡≡SMALLB≡≥		000001			    .IFNZ SMALLB
≠MOV≡≡TRNSPC≡≡R0≡≥	036470	012700	034764			MOV #TRNSPC,R0	;
≠JSR≡≡PC≡≡GETSBK≡≥	036474	004767	774756			JSR PC,GETSBK	;Allocate from small blocks
≠MOV≡≡R0≡≡R3≡≥	036500	010043			 	MOV R0,-(R3)	;Push new value cell pointer on interpreter stack.
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	036502	016746	773202			      MOV SBEVT,-(SP)
≥	036506	104012				104012
≥					    .IFF
≥					 	MOV #40,R0	;Number of words needed
≥						JSR PC,GTFREE	;R0 ← LOC[new block]
≥						MOV R0,-(R3)	;Push new value cell pointer on interpreter stack.
≥					    .ENDC
≠RTS≡≡PC≡≥	036510	000207				RTS PC		;Done
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 114
	INTERP PAL[HAL,HE]	PAGE 6 	Table of interpreter instructions

≥					;Variable declaration:  MVAR, KVAR;
≥					
≥					MVAR:
≥					
≠COMMEN≡≥				COMMENT ⊗ A list of arguments, each of which is an offset.  This list
≥				is terminated by a zero entry.  For each argument, a fresh graph node
≥				is created (with no value) and a pointer to it is placed in the
≥					environment at the desired offset, current level. ⊗
≥					
≠MOV≡≡IPC≡≡R4≡≡SP≡≥	036512	017446	000000			MOV @IPC(R4),-(SP)	;push offset
≠BIC≡≡SP≡≥	036516	042716	177400			BIC #177400,(SP);Get rid of level info.
≠BEQ≡≥	036522	001412				BEQ 1$		;If none, done
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	036524	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠CLR≡≡R0≡≥	036532	005000				CLR R0		;The new graph node should get no value cell.
≠JSR≡≡PC≡≡MAKEVN≡≥	036534	004767	023726			JSR PC,MAKEVN	;R0 ← LOC[a new variable node]
≠ADD≡≡ENV≡≡R4≡≡SP≡≥	036540	066416	000006			ADD ENV(R4),(SP);stack pointer into environment
≠MOV≡≡R0≡≡SP≡≥	036544	010036				MOV R0,@(SP)+	;Point the environment to the graph node
≠BR≡≡MVAR≡≥	036546	000761				BR  MVAR	;Repeat
≠TST≡≡SP≡≥	036550	005726			1$:	TST (SP)+	;Clean off stack
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	036552	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	036560	000207				RTS PC		;Done
≥					
≥					KVAR:
≥					
≠COMMEN≡≥				COMMENT ⊗ A list of arguments, each of which is an offset.  This list
≥				is terminated by a zero entry.  For each argument, the corresponding
≥				graph node is destroyed in the current environment.  Any function in
≥				the graph structure is thereby released.  (Attempt is made to
≥					validate any dependents first.) ⊗
≠MOV≡≡IPC≡≡R4≡≡R2≡≥	036562	017402	000000			MOV @IPC(R4),R2	;R2 ← offset
≠BIC≡≡R2≡≥	036566	042702	177400			BIC #177400,R2	;Get rid of level info.
≠BEQ≡≥	036572	001412				BEQ 1$		;If none, done
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	036574	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠ADD≡≡ENV≡≡R4≡≡R2≡≥	036602	066402	000006			ADD ENV(R4),R2	;R2 ← LOC[pointer at graph node]
≠MOV≡≡R2≡≡R0≡≥	036606	011200				MOV (R2),R0	;R0 ← LOC[graph node]
≠JSR≡≡PC≡≡DELVN≡≥	036610	004767	024002			JSR PC,DELVN	;Get this guy deleted
≠CLR≡≡R2≡≥	036614	005012				CLR (R2)	;Remove the pointer in the environment
≠BR≡≡KVAR≡≥	036616	000761				BR KVAR		;Repeat
≤BMPIPC≡≥					1$:	BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	036620	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	036626	000207				RTS PC		;Done
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 115
	INTERP PAL[HAL,HE]	PAGE 7 	Table of interpreter instructions

≥					;Stack ops: GTVAL, IGTVAL, CHNGE, ICHNGE, PUSH, POP, COPY, REPLACE, FLUSH
≥					
≥					GTVAL:
≠COMMEN≡≥				COMMENT ⊗ The argument is a level-offset pair.  The variable
≥				referenced by that pair is examined and a pointer to its value cell
≥					is placed on the stack. ⊗
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	036630	017400	000000			MOV @IPC(R4),R0	;Pick up level-offset name of argument
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	036634	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	036642	004767	777414			JSR PC,GETARG	;R0 ← LOC[LOC[desired graph node]]
≠MOV≡≡R0≡≡R0≡≥	036646	011000				MOV (R0),R0	;R0 ← LOC[desired graph node]
≠BEQ≡≥	036650	001423				BEQ 4$		;But if 0, then bug
≠JSR≡≡PC≡≡NOCMP≡≥	036652	004767	774500			JSR PC,NOCMP	;Don't compact for a bit
≤CALL≡≥					1$:	CALL GETVAL,<R0>;R0 ← value
≠MOV≡≡RF≡≡SP≡≥	036656	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R0
≠.IRP≡≥						       .IRP II,<R0>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R0≡≡SP≡≥	036660	010046					MOV	R0,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	036662	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	036666	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡GETVAL≡≥	036670	004767	022102			JSR	PC,GETVAL		;Call the routine
≠MOV≡≡R0≡≡R3≡≥	036674	010043				MOV R0,-(R3)	;Push value on interpreter stack.
≠JSR≡≡PC≡≡YESCMP≡≥	036676	004767	774476			JSR PC,YESCMP	;OK to compact now
≠BEQ≡≥	036702	001401				BEQ 3$		;But if 0, then bug
≤CCC≡≥					2$:	CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	036704	000207				RTS PC		;Done
≤HALERR≡≥					3$:	HALERR GTVMS1	;Complain
≠MOV≡≡GTVMS1≡≡SP≡≥	036706	012746	036732			MOV #GTVMS1,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	036712	004777	755074			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤SCC≡≥						SCC		;Set condition code
≥					;	MOV #2,R0	;Set condition code.  Not used right now. (maybe use TST PC)
≠RTS≡≡PC≡≥	036716	000207				RTS PC		;Done
≤HALERR≡≥					4$:	HALERR GTVMS2	;Complain
≠MOV≡≡GTVMS2≡≡SP≡≥	036720	012746	037002			MOV #GTVMS2,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	036724	004777	755062			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠BR≡≥	036730	000765				BR 2$		;But comply
≤ASCIE≡≥					GTVMS1:	ASCIE </GTVAL FOUND A NULL VALUE.  MAY CONTINUE/>
≠.ASCIZ≡≥	036732	   107		
≥	036733	   124		
≥	036734	   126		
≥	036735	   101		
≥	036736	   114		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 116
	INTERP PAL[HAL,HE]	PAGE 7.1 	Table of interpreter instructions

≥	036737	   040		
≥	036740	   106		
≥	036741	   117		
≥	036742	   125		
≥	036743	   116		
≥	036744	   104		
≥	036745	   040		
≥	036746	   101		
≥	036747	   040		
≥	036750	   116		
≥	036751	   125		
≥	036752	   114		
≥	036753	   114		
≥	036754	   040		
≥	036755	   126		
≥	036756	   101		
≥	036757	   114		
≥	036760	   125		
≥	036761	   105		
≥	036762	   056		
≥	036763	   040		
≥	036764	   040		
≥	036765	   115		
≥	036766	   101		
≥	036767	   131		
≥	036770	   040		
≥	036771	   103		
≥	036772	   117		
≥	036773	   116		
≥	036774	   124		
≥	036775	   111		
≥	036776	   116		
≥	036777	   125		
≥	037000	   105		
≥	037001	   000		
≥					       .ASCIZ /GTVAL FOUND A NULL VALUE.  MAY CONTINUE/
≠.EVEN≡≥		037002			       .EVEN
≤ASCIE≡≥					GTVMS2:	ASCIE </GTVAL FOUND A NULL GRAPH NODE.  MAY CONTINUE/>
≠.ASCIZ≡≥	037002	   107		
≥	037003	   124		
≥	037004	   126		
≥	037005	   101		
≥	037006	   114		
≥	037007	   040		
≥	037010	   106		
≥	037011	   117		
≥	037012	   125		
≥	037013	   116		
≥	037014	   104		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 117
	INTERP PAL[HAL,HE]	PAGE 7.2 	Table of interpreter instructions

≥	037015	   040		
≥	037016	   101		
≥	037017	   040		
≥	037020	   116		
≥	037021	   125		
≥	037022	   114		
≥	037023	   114		
≥	037024	   040		
≥	037025	   107		
≥	037026	   122		
≥	037027	   101		
≥	037030	   120		
≥	037031	   110		
≥	037032	   040		
≥	037033	   116		
≥	037034	   117		
≥	037035	   104		
≥	037036	   105		
≥	037037	   056		
≥	037040	   040		
≥	037041	   040		
≥	037042	   115		
≥	037043	   101		
≥	037044	   131		
≥	037045	   040		
≥	037046	   103		
≥	037047	   117		
≥	037050	   116		
≥	037051	   124		
≥	037052	   111		
≥	037053	   116		
≥	037054	   125		
≥	037055	   105		
≥	037056	   000		
≥					       .ASCIZ /GTVAL FOUND A NULL GRAPH NODE.  MAY CONTINUE/
≠.EVEN≡≥		037060			       .EVEN
≥					
≥					IGTVAL:	
≠COMMEN≡≥				COMMENT ⊗ Immediate version of GTVAL.  The argument points directly
≥				to the graph node whose value is desired.  A pointer to the value
≥					cell is placed on the stack. ⊗
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	037060	017400	000000			MOV @IPC(R4),R0	;R0 ← LOC[desired graph node]
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	037064	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡NOCMP≡≥	037072	004767	774260			JSR PC,NOCMP	;Don't compact for a bit
≤CALL≡≥						CALL GETVAL,<R0>;R0 ← value
≠MOV≡≡RF≡≡SP≡≥	037076	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R0
≠.IRP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 118
	INTERP PAL[HAL,HE]	PAGE 7.3 	Table of interpreter instructions

≥						       .IRP II,<R0>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R0≡≡SP≡≥	037100	010046					MOV	R0,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	037102	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	037106	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡GETVAL≡≥	037110	004767	021662			JSR	PC,GETVAL		;Call the routine
≠MOV≡≡R0≡≡R3≡≥	037114	010043				MOV R0,-(R3)	;Push value on interpreter stack.
≠JSR≡≡PC≡≡YESCMP≡≥	037116	004767	774256			JSR PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	037122	000207				RTS PC		;Done
≥					
≥					CHNGE:
≠COMMEN≡≥				COMMENT ⊗ Pops the value from top of stack into the graph structure
≥					pointed to by the level-offset pair given in the argument.  ⊗
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	037124	017400	000000			MOV @IPC(R4),R0	;Pick up level-offset name of argument
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	037130	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	037136	004767	777120			JSR PC,GETARG	;R0 ← LOC[LOC[Desired graph node]]
≠MOV≡≡R0≡≡R0≡≥	037142	011000				MOV (R0),R0	;R0 ← LOC[Desired graph node]
≠BEQ≡≥	037144	001416				BEQ 1$		;If any
≠JSR≡≡PC≡≡NOCMP≡≥	037146	004767	774204			JSR PC,NOCMP	;Don't compact for a bit
≤CALL≡≥						CALL CHANGE,<R0,(R3)>
≠MOV≡≡RF≡≡SP≡≥	037152	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R0,(R3)
≠.IRP≡≥						       .IRP II,<R0,(R3)>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R0≡≡SP≡≥	037154	010046					MOV	R0,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡R3≡≡SP≡≥	037156	011346					MOV	(R3),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	037160	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	037164	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡CHANGE≡≥	037166	004767	021306			JSR	PC,CHANGE		;Call the routine
≠JSR≡≡PC≡≡YESCMP≡≥	037172	004767	774202			JSR PC,YESCMP	;OK to compact now
≠TST≡≡R3≡≥	037176	005723				TST (R3)+	;Pop stack
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	037200	000207				RTS PC		;Done
≤HALERR≡≥					1$:	HALERR 2$	;Complain
≠MOV≡≡SP≡≥	037202	012746	037216			MOV #2$,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 119
	INTERP PAL[HAL,HE]	PAGE 7.4 	Table of interpreter instructions

≥	037206	004777	754600			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠TST≡≡R3≡≥	037212	005723				TST (R3)+	;Get rid of the value
≤SCC≡≥						SCC		;Set condition code
≥					;	MOV #2,R0	;Set condition code.  Not used right now. (maybe use TST PC)
≠RTS≡≡PC≡≥	037214	000207				RTS PC		;Done
≤ASCIE≡≥					2$:	ASCIE </CAN'T ASSIGN INTO UNINITIALIZED VARIABLE/>
≠.ASCIZ≡≥	037216	   103		
≥	037217	   101		
≥	037220	   116		
≥	037221	   047		
≥	037222	   124		
≥	037223	   040		
≥	037224	   101		
≥	037225	   123		
≥	037226	   123		
≥	037227	   111		
≥	037230	   107		
≥	037231	   116		
≥	037232	   040		
≥	037233	   111		
≥	037234	   116		
≥	037235	   124		
≥	037236	   117		
≥	037237	   040		
≥	037240	   125		
≥	037241	   116		
≥	037242	   111		
≥	037243	   116		
≥	037244	   111		
≥	037245	   124		
≥	037246	   111		
≥	037247	   101		
≥	037250	   114		
≥	037251	   111		
≥	037252	   132		
≥	037253	   105		
≥	037254	   104		
≥	037255	   040		
≥	037256	   126		
≥	037257	   101		
≥	037260	   122		
≥	037261	   111		
≥	037262	   101		
≥	037263	   102		
≥	037264	   114		
≥	037265	   105		
≥	037266	   000		
≥					       .ASCIZ /CAN'T ASSIGN INTO UNINITIALIZED VARIABLE/
≠.EVEN≡≥		037270			       .EVEN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 120
	INTERP PAL[HAL,HE]	PAGE 7.5 	Table of interpreter instructions

≥					
≥					ICHNGE:
≠COMMEN≡≥				COMMENT ⊗ Immediate version of CHNGE.  Pops the value from top of
≥					stack into the graph structure pointed to directly by the argument. ⊗
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	037270	017400	000000			MOV @IPC(R4),R0	;R0 ← LOC[desired graph node]
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	037274	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡NOCMP≡≥	037302	004767	774050			JSR PC,NOCMP	;Don't compact for a bit
≤CALL≡≥						CALL CHANGE,<R0,(R3)>
≠MOV≡≡RF≡≡SP≡≥	037306	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R0,(R3)
≠.IRP≡≥						       .IRP II,<R0,(R3)>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R0≡≡SP≡≥	037310	010046					MOV	R0,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡R3≡≡SP≡≥	037312	011346					MOV	(R3),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	037314	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	037320	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡CHANGE≡≥	037322	004767	021152			JSR	PC,CHANGE		;Call the routine
≠JSR≡≡PC≡≡YESCMP≡≥	037326	004767	774046			JSR PC,YESCMP	;OK to compact now
≠TST≡≡R3≡≥	037332	005723			POP:	TST (R3)+	;Pop stack
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	037334	000207				RTS PC		;Done
≥					
≠MOV≡≡IPC≡≡R4≡≡R3≡≥	037336	017443	000000		PUSH:	MOV @IPC(R4),-(R3);Put argument directly on stack
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	037342	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	037350	000207				RTS PC		;Done
≥					
≥					; Interpreter routine.  Copies the nth element in stack to the top,
≥					; where the curent top is 0. 
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	037352	017400	000000		COPY:	MOV @IPC(R4),R0	;Pick up argument.
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	037356	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠ADD≡≡R0≡≡R0≡≥	037364	060000				ADD R0,R0	;Double R0 to make it in bytes
≠ADD≡≡R3≡≡R0≡≥	037366	060300				ADD R3,R0	;R0 ← LOC[stack element to be copied to top]
≠MOV≡≡R0≡≡R3≡≥	037370	011043				MOV (R0),-(R3)	;Copy it onto top of stack.
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	037372	000207				RTS PC		;Done
≥					
≠MOV≡≡IPC≡≡R4≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 121
	INTERP PAL[HAL,HE]	PAGE 7.6 	Table of interpreter instructions

≥	037374	017400	000000		REPLAC:	MOV @IPC(R4),R0	;Pick up argument.
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	037400	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠ADD≡≡R0≡≡R0≡≥	037406	060000				ADD R0,R0	;Double R0 to make it in bytes
≠ADD≡≡R3≡≡R0≡≥	037410	060300				ADD R3,R0	;R0 ← LOC[stack element to be copied into]
≠MOV≡≡R3≡≡R0≡≥	037412	012310				MOV (R3)+,(R0)	;Copy verge of stack into it.
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	037414	000207				RTS PC		;Done
≥					
≠MOV≡≡STKBAS≡≡R4≡≡R3≡≥	037416	016403	000004		FLUSH:	MOV STKBAS(R4),R3;Reset the stack base.
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	037422	000207				RTS PC		;Done
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 122
	INTERP PAL[HAL,HE]	PAGE 8 	Table of interpreter instructions

≥					;Global reference routines GLBLNK, GLOBSR.
≥					
≥					GLBLNK:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Expects two arguments at the IPC, a level-offset, and two
≥				words of a Rad50 name.  Makes sure that this global is linked in to
≥				the environment at the given level-offset.  If not, a search is
≥				made for it, and the result is put in the environment.
≥					⊗
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	037424	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset
≤BMPIPC≡≥						BMPIPC		;Bump IPC past the level-offset
≠ADD≡≡IPC≡≡R4≡≥	037430	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	037436	004767	776620			JSR PC,GETARG	;R0 ← LOC[environment cell]
≠TST≡≡R0≡≥	037442	005710				TST (R0)	;Graph node yet?
≠BEQ≡≥	037444	001407				BEQ 2$		;No, must search for it
≤BMPIPC≡≥					1$:	BMPIPC		;Bump IPC past the Rad50 name
≠ADD≡≡IPC≡≡R4≡≥	037446	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤BMPIPC≡≥						BMPIPC		;Bump IPC past the Rad50 name
≠ADD≡≡IPC≡≡R4≡≥	037454	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠RTS≡≡PC≡≥	037462	000207				RTS PC		;Done
≠MOV≡≡R0≡≡R2≡≥	037464	010002			2$:	MOV R0,R2	;R2 ← LOC[environment cell]
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	037466	016400	000000			MOV IPC(R4),R0	;R0 ← LOC[Rad50 representation]
≠JSR≡≡PC≡≡GLOBSR≡≥	037472	004767	000074			JSR PC,GLOBSR	;R0 ← LOC[new or old graph node]
≠MOV≡≡R0≡≡R2≡≥	037476	010012				MOV R0,(R2)	;Stow LOC[graph node] in the environment cell
≠BR≡≥	037500	000762				BR 1$		;Ready to return
≥					
≡MAXGLB≠≥		000010			MAXGLB == 10		;Maximum number of globals allowed
≠.BLKW≡≡MAXGLB≡≥		037562			GLBTAB:	.BLKW 3*MAXGLB	;Three words per global:  2 of Rad50, one
≥									;pointer to the graph node.
≥									;To be searched linearly.
≠.BLKW≡≥		037570			GLBLIM:	.BLKW 3		;Overflow place for GLBTAB
≠.BLKW≡≥		037572			GLBEND:	.BLKW 1		;Points to next free place in GLBTAB
≥					
≥					GLOBSR:
≠COMMEN≡≥				COMMENT ⊗ R0 = LOC[two words of Rad50].  Tries to find the
≥				appropriate graph node using the GLBTAB, and if it fails, makes a new
≥				graph node and inserts it in the GLBTAB.  In any case, returns R0 ←
≥					LOC[new or old graph node].  ⊗
≤EVWAIT≡≥						EVWAIT GLBEVT	;Critical region starts here
≤.ARG≡≥						  .ARG GLBEVT
≠.LIF≡≥						    .LIF NB GLBEVT
≠MOV≡≡GLBEVT≡≡SP≡≥	037572	016746	775514			      MOV GLBEVT,-(SP)
≥	037576	104010				104010
≠MOV≡≡GLBEND≡≡R1≡≥	037600	016701	777764			MOV GLBEND,R1	;R1 ← LOC[next free place in GLBTAB]
≠MOV≡≡R0≡≡R1≡≥	037604	011021				MOV (R0),(R1)+	;Put the word sought at next free place
≠MOV≡≡R0≡≡R1≡≥	037606	016021	000002			MOV 2(R0),(R1)+	;
≠CLR≡≡R1≡≥	037612	005011				CLR (R1)	; with a 0 for a graph node pointer.
≠MOV≡≡GLBTAB≡≡R1≡≥	037614	012701	037502			MOV #GLBTAB,R1	;R1 ← LOC[start of GLBTAB]
≠CMP≡≡R0≡≡R1≡≥	037620	021011			1$:	CMP (R0),(R1)	;MATCH?
≠BNE≡≥	037622	001004				BNE 2$		;No.
≠CMP≡≡R0≡≡R1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 123
	INTERP PAL[HAL,HE]	PAGE 8.1 	Table of interpreter instructions

≥	037624	026061	000002	000002		CMP 2(R0),2(R1)	;Second word match?
≠BEQ≡≥	037632	001403				BEQ 3$		;Yes.
≠ADD≡≡R1≡≥	037634	062701	000006		2$:	ADD #6,R1	;
≠BR≡≥	037640	000767				BR  1$		;Try again.
≠MOV≡≡R1≡≡R0≡≥	037642	016100	000004		3$:	MOV 4(R1),R0	;R0 ← LOC[graph node]
≠BNE≡≥	037646	001022				BNE 5$		;If it is not zero, we are done
≠ADD≡≡GLBEND≡≥	037650	062767	000006	777712		ADD #6,GLBEND	;Move the end of the table down one entry
≠CMP≡≡GLBEND≡≡GLBLIM≡≥	037656	026727	777706	037562		CMP GLBEND,#GLBLIM	;Too far?
≠BLT≡≥	037664	002404				BLT 4$		;No
≤HALERR≡≥						HALERR GLOBMS	;Yes
≠MOV≡≡GLOBMS≡≡SP≡≥	037666	012746	037724			MOV #GLOBMS,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	037672	004777	754114			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠MOV≡≡R1≡≡SP≡≥	037676	010146			4$:	MOV R1,-(SP)	;Save place in GLBTAB
≠CLR≡≡R0≡≥	037700	005000				CLR R0		;New graph node should have no value cell.
≠JSR≡≡PC≡≡MAKEVN≡≥	037702	004767	022560			JSR PC,MAKEVN	;R0 ← LOC[a new variable node]
≠MOV≡≡SP≡≡R1≡≥	037706	012601				MOV (SP)+,R1	;Restore place in GLBTAB
≠MOV≡≡R0≡≡R1≡≥	037710	010061	000004			MOV R0,4(R1)	;store LOC[new graph node] in GLBTAB
≤EVSIG≡≥					5$:	EVSIG GLBEVT	;Critical region ends here
≤.ARG≡≥						  .ARG GLBEVT
≠.LIF≡≥						    .LIF NB GLBEVT
≠MOV≡≡GLBEVT≡≡SP≡≥	037714	016746	775372			      MOV GLBEVT,-(SP)
≥	037720	104012				104012
≠RTS≡≡PC≡≥	037722	000207				RTS PC		;Done
≤ASCIE≡≥					GLOBMS:	ASCIE </TOO MANY GLOBALS/>
≠.ASCIZ≡≥	037724	   124		
≥	037725	   117		
≥	037726	   117		
≥	037727	   040		
≥	037730	   115		
≥	037731	   101		
≥	037732	   116		
≥	037733	   131		
≥	037734	   040		
≥	037735	   107		
≥	037736	   114		
≥	037737	   117		
≥	037740	   102		
≥	037741	   101		
≥	037742	   114		
≥	037743	   123		
≥	037744	   000		
≥					       .ASCIZ /TOO MANY GLOBALS/
≠.EVEN≡≥		037746			       .EVEN
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 124
	INTERP PAL[HAL,HE]	PAGE 9 	Table of interpreter instructions

≥					;Flow-of-control: PROC, RETURN, ABORT, GODDT
≥					
≥					PROC:
≥					;Procedure call.  Arguments: 
≥					;	Destination.
≥					;	List of variables which are to be inserted in appropriate 
≥					;	  locations in the local storage of procedure.  These are
≥					;	  in the format variable (ie level-offset pair), new offset
≥					;	  (right justified in the second word).
≥					;	  There is a zero word to finish these.
≥					;At the destination address can be found:
≡II≠≥		000000				II == 0
≤XX≡≥						XX FSLGTH	;Number of words to get from free storage 
≠.IFDF≡≡FSLGTH≡≥						   .IFDF FSLGTH
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using FSLGTH in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡FSLGTH≠≥		000000				    FSLGTH == II
≡II≡≡II≠≥		000002				    II == II+2
≥								;for local variable pointers
≤XX≡≥						XX PLEV		;Lexical level of procedure
≠.IFDF≡≡PLEV≡≥						   .IFDF PLEV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using PLEV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡PLEV≠≥		000002				    PLEV == II
≡II≡≡II≠≥		000004				    II == II+2
≡II≡≡DSLGTH≠≥		000004				DSLGTH == II	;Number of words before code starts
≥					;Value parameters should have first been copied first into local temps
≥					;  (which have been arranged by the compiler), and then the temps are
≥					;  passed by reference.  Eventual problem: to know which variables to
≥					;  really kill as the procedure is exited. 
≥					
≠MOV≡≡IPC≡≡R4≡≡R2≡≥	037746	017402	000000			MOV @IPC(R4),R2	;R2 ← LOC[destination]
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	037752	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠MOV≡≡FSLGTH≡≡R2≡≡R0≡≥	037760	016200	000000			MOV FSLGTH(R2),R0	;R0 ← Number of words to get.
≠JSR≡≡PC≡≡GTFREE≡≥	037764	004767	770256			JSR PC,GTFREE	;R0 ← LOC[block with that number of words]
≥					
≥					      ;initialize pointer to lexical level:
≠MOV≡≡PLEV≡≡R2≡≡R1≡≥	037770	016201	000002			MOV PLEV(R2),R1	;R1 ← Lexical level of procedure
≠MOV≡≡ENV≡≡R4≡≡R2≡≥	037774	016402	000006			MOV ENV(R4),R2	;R2 ← LOC[current environment]
≠SUB≡≡LEV≡≡R4≡≡R1≡≥	040000	166401	000010			SUB LEV(R4),R1	;R1 ← Difference in levels: desired-got
≠BEQ≡≥	040004	001404				BEQ 2$		;Diff=0; can use R2 as pointer at right environment.
≠MOV≡≡SLINK≡≡R2≡≡R2≡≥	040006	016202	000000		1$:	MOV SLINK(R2),R2;No, must go up a level.  R2 ← LOC[base of upper area]
≠INC≡≡R1≡≥	040012	005201				INC R1		;R1 ← New difference in levels
≠BNE≡≥	040014	001374				BNE 1$		;If not yet good, then move up another level
≠MOV≡≡R2≡≡SLINK≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 125
	INTERP PAL[HAL,HE]	PAGE 9.1 	Table of interpreter instructions

≥	040016	010260	000000		2$:	MOV R2,SLINK(R0);SLINK[new environment] ← correct global environment
≥					
≥					      ;Put copies of local variables in new area
≠MOV≡≡R0≡≡SP≡≥	040022	010046				MOV R0,-(SP)	;Stack LOC[new environment]
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	040024	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset pair for an argument
≠BEQ≡≥	040030	001417				BEQ 4$		;If there are no more, go to next phase
≤BMPIPC≡≥					3$:	BMPIPC		;Else bump IPC
≠ADD≡≡IPC≡≡R4≡≥	040032	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	040040	004767	776216			JSR PC,GETARG	;R0 ← LOC[LOC[graph node]]
≠MOV≡≡IPC≡≡R4≡≡R1≡≥	040044	017401	000000			MOV @IPC(R4),R1	;R1 ← offset in new block
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	040050	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠ADD≡≡SP≡≡R1≡≥	040056	061601				ADD (SP),R1	;R1 ← LOC[place in new environment to put pointer]
≠MOV≡≡R0≡≡R1≡≥	040060	011011				MOV (R0),(R1)	;new environment gets pointer to LOC[argument graph node]
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	040062	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset pair for an argument
≠BNE≡≥	040066	001361				BNE 3$		;If there are more, go back and treat them
≤BMPIPC≡≥					4$:	BMPIPC		;Bump IPC one last time
≠ADD≡≡IPC≡≡R4≡≥	040070	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≥					
≥					      ;Save the old context in the new area
≠MOV≡≡SP≡≡R1≡≥	040076	012601				MOV (SP)+,R1	;R1 ← LOC[new environment]
≠MOV≡≡LEV≡≡R4≡≡OLEV≡≡R1≡≥	040100	016461	000010	000002		MOV LEV(R4),OLEV(R1)	;Store the old level
≠MOV≡≡ENV≡≡R4≡≡OENV≡≡R1≡≥	040106	016461	000006	000004		MOV ENV(R4),OENV(R1)	;Store the old environment location
≠MOV≡≡IPC≡≡R4≡≡OIPC≡≡R1≡≥	040114	016461	000000	000006		MOV IPC(R4),OIPC(R1)	;Store the return address
≥					
≥					      ;Set up the new context for procedure
≠MOV≡≡PLEV≡≡R2≡≡LEV≡≡R4≡≥	040122	016264	000002	000010		MOV PLEV(R2),LEV(R4)	;New lexical level
≠MOV≡≡R1≡≡ENV≡≡R4≡≥	040130	010164	000006			MOV R1,ENV(R4)	;New environment location
≠ADD≡≡DSLGTH≡≡R2≡≥	040134	062702	000004			ADD #DSLGTH,R2	;R2 ← Place where execution should begin
≠MOV≡≡R2≡≡IPC≡≡R4≡≥	040140	010264	000000			MOV R2,IPC(R4)	;New program counter
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	040144	000207				RTS PC		;Done
≥					
≥					
≥					RETURN:
≥					;Returns from a procedure call to calling program. Since variables are
≥					;passed by reference, it is not necessary to do any copying of values.
≥					;All that is needed is to restore the context of the caller and to
≥					;discard the display.
≠MOV≡≡ENV≡≡R4≡≡R0≡≥	040146	016400	000006			MOV ENV(R4),R0	;R0 ← LOC[current environment]
≠MOV≡≡OLEV≡≡R0≡≡LEV≡≡R4≡≥	040152	016064	000002	000010		MOV OLEV(R0),LEV(R4)	;Restore the old lexical level
≠MOV≡≡OENV≡≡R0≡≡ENV≡≡R4≡≥	040160	016064	000004	000006		MOV OENV(R0),ENV(R4)	;Restore the old environment
≠MOV≡≡OIPC≡≡R0≡≡IPC≡≡R4≡≥	040166	016064	000006	000000		MOV OIPC(R0),IPC(R4)	;Restore the IPC
≠JSR≡≡PC≡≡RLFREE≡≥	040174	004767	770410			JSR PC,RLFREE	;Release storage of old display
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	040200	000207				RTS PC		;Done
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 126
	INTERP PAL[HAL,HE]	PAGE 9.2 	Table of interpreter instructions

≥					ABORT:
≥					;Aborts current motions
≥					;This should be cleaned up sometime.
≠MOV≡≡R1≡≥	040202	012701	000016			MOV	#16,R1	;First stop all devices - 2 arms (6 joints/arm) & 2 hands
≠MOV≡≡LDVCPT≡≡R0≡≥	040206	016700	753616			MOV	LDVCPTR,R0	;R0 ← LOC[table of device pointers]
≠MOV≡≡R0≡≡R2≡≥	040212	012002			1$:	MOV	(R0)+,R2	;R2 ← device block
≠BEQ≡≥	040214	001402				BEQ	2$		;If any
≠BIS≡≡R2≡≥	040216	052712	100000			BIS	#100000,(R2)	;Stop this device
≠SOB≡≡R1≡≥	040222	077105			2$:	SOB	R1,1$		;Repeat	till all devices stopped
≥						;SLEEP	#144		;Should pause for a bit (1/10 sec) here but...
≥									;  if anything gets printed no problem
≤CCC≡≥						CCC			;Clear the condition codes
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	040224	000207				RTS	PC		; & Return
≥					
≠BPT≡≠BPT≡≥	040226	000003			GODDT:	BPT			;break to DDT
≤CCC≡≥						CCC			;Clear the condition codes
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	040230	000207				RTS	PC		; and Return
≥					
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 127
	INTERP PAL[HAL,HE]	PAGE 10 	Table of interpreter instructions

≥					;  FORCHK, JUMP, JUMPC
≥					
≥					FORCHK:	
≥					;Assume that the stack has, from surface in, the increment, the
≥					;  final value, and the control variable's value, all of which are
≥					;  scalar values.  If (FINAL-CONVAR)*(INCREMENT) ≥ 0 then this is a
≥					;  no-op; otherwise, jump to the destination. 
≥					;Arguments:  destination.
≠LDF≡≡R3≡≡AC0≡≥	040232	172473	000002			LDF @2(R3),AC0	;AC0 ← final value
≠SUBF≡≡R3≡≡AC0≡≥	040236	173073	000004			SUBF @4(R3),AC0	;AC0 ← final - current
≠MULF≡≡R3≡≡AC0≡≥	040242	171073	000000			MULF @(R3),AC0	;AC0 ← (final - current)*increment
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	040246	017400	000000			MOV @IPC(R4),R0	;R0 ← destination
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	040252	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠CFCC≡≠CFCC≡≥	040260	170000				CFCC		;
≠BGE≡≥	040262	002002				BGE 1$		;Shall this be a no-op?
≠MOV≡≡R0≡≡IPC≡≡R4≡≥	040264	010064	000000			MOV R0,IPC(R4)	;No; set new IPC.
≠CLR≡≡R0≡≥	040270	005000			1$:	CLR R0		;
≠RTS≡≡PC≡≥	040272	000207				RTS PC		;Done
≥					
≥					JUMP:
≥					;Takes one argument: the new address.
≠MOV≡≡IPC≡≡R4≡≡IPC≡≡R4≡≥	040274	017464	000000	000000		MOV @IPC(R4),IPC(R4)
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	040302	000207				RTS PC		;Done
≥					
≥					JUMPC:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Takes one argument: the destination address. 
≥				The condition queries the top of the stack and pops it, assuming it
≥				to be a scalar.  The interpreter jumps to the destination address if
≥					the value of the scalar is false (0). rewritten 9-14-76 by arg ⊗
≠LDF≡≡R3≡≡AC0≡≥	040304	172433				LDF	@(R3)+,AC0	;Get value of boolean
≠CFCC≡≠CFCC≡≥	040306	170000				CFCC			;copy condition codes
≠BEQ≡≥	040310	001404				BEQ	1$		;if false succeed - take branch
≤BMPIPC≡≥						BMPIPC			;skip over address
≠ADD≡≡IPC≡≡R4≡≥	040312	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠RTS≡≡PC≡≥	040320	000207				RTS	PC		; & return
≠MOV≡≡IPC≡≡R4≡≡IPC≡≡R4≡≥	040322	017464	000000	000000	1$:	MOV	@IPC(R4),IPC(R4); branch
≠RTS≡≡PC≡≥	040330	000207				RTS	PC		; & return
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 128
	INTERP PAL[HAL,HE]	PAGE 11 	Table of interpreter instructions

≥					;  SPAWN, SPROUT, TERMINATE
≥					
≥					
≥					SPAWN:	;Utility routine
≥					
≠COMMEN≡≥				COMMENT ⊗ Takes two arguments: In R0, the IPC of the interpreter to
≥				spawn, and in R1, the event (if any) to put in EVT of the new
≥				interpreter.  The inferior will have the same environment as the
≥				superior.  Creates an interpreter status block, stack, process
≥				descriptor, and is ready for a SCHEDU when it returns the process
≥					descriptor in R0. ⊗
≥					
≠MOV≡≡R1≡≡SP≡≥	040332	010146				MOV R1,-(SP)	;Save the EVT
≠MOV≡≡R0≡≡SP≡≥	040334	010046				MOV R0,-(SP)	;Save the new IPC
≠MOV≡≡ISBS≡≡R0≡≥	040336	012700	000017			MOV #ISBS,R0	;R0 ← Size (in words) of an interpreter status block
≠JSR≡≡PC≡≡GTFREE≡≥	040342	004767	767700			JSR PC,GTFREE	;R0 ← LOC[new interpreter status block]
≠MOV≡≡SP≡≡IPC≡≡R0≡≥	040346	012660	000000			MOV (SP)+,IPC(R0);new IPC ← first argument
≠MOV≡≡ENV≡≡R4≡≡ENV≡≡R0≡≥	040352	016460	000006	000006		MOV ENV(R4),ENV(R0)	;new ENV ← old ENV
≠MOV≡≡LEV≡≡R4≡≡LEV≡≡R0≡≥	040360	016460	000010	000010		MOV LEV(R4),LEV(R0)	;new LEV ← old LEV
≠.IFNZ≡≡ALAID≡≥		000001			    .IFNZ ALAID
≠MOV≡≡DEBMOD≡≡R4≡≡DEBMOD≡≡R0≡≥	040366	016460	000032	000032		MOV DEBMOD(R4),DEBMOD(R0)	;new DEBMOD ← old DEBMOD
≥					    .ENDC
≤EVWAIT≡≥						EVWAIT INTEVT	;Interlock sensitive operation.
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	040374	016746	774710			      MOV INTEVT,-(SP)
≥	040400	104010				104010
≠MOV≡≡NXTINT≡≡ISTBLK≡≡R1≡≥	040402	012701	063224			MOV #NXTINT+ISTBLK,R1	;Link into the interpreter list.
≠MOV≡≡R1≡≡NXTINT≡≡R0≡≥	040406	011160	000002			MOV (R1),NXTINT(R0)	;
≠MOV≡≡R0≡≡R1≡≥	040412	010011				MOV R0,(R1)	;
≤EVSIG≡≥						EVSIG INTEVT	;End of interlock
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	040414	016746	774670			      MOV INTEVT,-(SP)
≥	040420	104012				104012
≠MOV≡≡SP≡≡EVT≡≡R0≡≥	040422	012660	000016			MOV (SP)+,EVT(R0);new EVT ← second argument.
≠MOV≡≡R0≡≡SP≡≥	040426	010046				MOV R0,-(SP)	;Save LOC[new interpreter status block]
≠MOV≡≡INSTSZ≡≡R0≡≥	040430	012700	000020			MOV #INSTSZ,R0	;R0 ← Size needed for an interpreter stack
≠JSR≡≡PC≡≡GTFREE≡≥	040434	004767	767606			JSR PC,GTFREE	;R0 ← LOC[new interpreter stack]
≠MOV≡≡SP≡≡R1≡≥	040440	012601				MOV (SP)+,R1	;R1 ← LOC[new interpreter status block]
≠MOV≡≡R0≡≡STKBAS≡≡R1≡≥	040442	010061	000004			MOV R0,STKBAS(R1)	;Store away new stack base
≠ADD≡≡INSTSZ≡≡R0≡≥	040446	062700	000040			ADD #2*INSTSZ,R0	;R0 ← LOC[top of new stack] (INSTSZ is in bytes)
≠MOV≡≡R1≡≡SP≡≥	040452	010146				MOV R1,-(SP)	;Save R1
≠MOV≡≡R0≡≡SP≡≥	040454	010046				MOV R0,-(SP)	;Save R0
≠MOV≡≡R0≡≥	040456	012700	000210			MOV #210,R0	;Room for process descriptor
≠JSR≡≡PC≡≡GTFREE≡≥	040462	004767	767560			JSR PC,GTFREE	;R0 ← LOC[new process descriptor]
≠MOV≡≡UFPUSE≡≡UGRSAV≡≡PDBSTA≡≡R0≡≥	040466	012760	104000	000000		MOV #UFPUSE+UGRSAV,PDBSTA(R0);Use floating point, use saved registers.
≠MOV≡≡UPDLEN≡≡R0≡≥	040474	012760	000420	000002		MOV #420,UPDLEN(R0)	;Length of PCB
≥					;	MOV (R2),PDBR2(R0)	;Transfer register 2 (not currently necessary)
≠MOV≡≡SP≡≡R1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 129
	INTERP PAL[HAL,HE]	PAGE 11.1 	Table of interpreter instructions

≥	040502	012601				MOV (SP)+,R1		;R1 ← LOC[new interpreter stack top]
≠MOV≡≡R1≡≡PDBR3≡≡R0≡≥	040504	010160	000034			MOV R1,PDBR3(R0)	;Store away new interp stack pointer (reg 3)
≠MOV≡≡SP≡≡R1≡≥	040510	012601				MOV (SP)+,R1		;R1 ← LOC[new ISB]
≠MOV≡≡R0≡≡PCB≡≡R1≡≥	040512	010061	000014			MOV R0,PCB(R1)		;Store away LOC[PCB] in new ISB
≠MOV≡≡R1≡≡PDBR4≡≡R0≡≥	040516	010160	000036			MOV R1,PDBR4(R0)	;Store away LOC[ISB] in reg 4 of PCB
≥					;	MOV R5,PDBR5(R0)	;Store away reg 5 (not currently necessary)
≠MOV≡≡SP≡≡R1≡≥	040522	010601				MOV SP,R1	;
≠TST≡≡R1≡≥	040524	005721				TST (R1)+	;
≠MOV≡≡R1≡≡PDBSP≡≡R0≡≥	040526	010160	000014			MOV R1,PDBSP(R0)	;Store away the new stack pointer (reg 6)
≠MOV≡≡INTERP≡≡PDBPC≡≡R0≡≥	040532	012760	036016	000016		MOV #INTERP,PDBPC(R0);Store away the new PC
≠MOV≡≡PCB≡≡R4≡≡R1≡≥	040540	016401	000014			MOV PCB(R4),R1		;Use same UIMAP, UDMAP that we are using.
≠MOV≡≡UIMAP≡≡R1≡≡UIMAP≡≡R0≡≥	040544	016160	000022	000022		MOV UIMAP(R1),UIMAP(R0)	;
≠MOV≡≡UDMAP≡≡R1≡≡UDMAP≡≡R0≡≥	040552	016160	000024	000024		MOV UDMAP(R1),UDMAP(R0)	;
≥					
≠RTS≡≡PC≡≥	040560	000207				RTS PC		;Done
≥					
≥					; These are the appropriate scheduling commands:
≥					;	SCHEDU R0,#INTERP,#1,#2;Cause the new process to be started, suspended
≥					;	FORK R0,#INTERP,#1	;Cause the new process to be started.
≥					
≥					SPROUT:	;Interpreter routine
≥					
≠COMMEN≡≥				COMMENT ⊗ Arguments: One address in pseudo-code for each of the
≥				several forks starting up, followed by a 0 word.  This is to be used
≥				only for cobegins, not for servos.  Each new interpreter is given an
≥				interpreter status block and is then scheduled.  As each terminates,
≥				it signals its defining event.  Since each of these has the same
≥				event, the current interpreter need only wait until they all happen.
≥					⊗
≥					
≠MOV≡≡R3≡≡SP≡≥	040562	010346				MOV R3,-(SP)	;Save R3.  Caution:  cannot use interpreter stack now.
≠CLR≡≡R3≡≥	040564	005003				CLR R3		;R3 is the count of how many inferiors to spawn.
≤EVMAK≡≥						EVMAK		;-(SP) ← Event identifier for communication with infs.
≥	040566	104004				104004
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	040570	017400	000000		1$:	MOV @IPC(R4),R0	;R0 ← next argument (IPC)
≠BEQ≡≥	040574	001437				BEQ 2$		;If zero, then we have spawned all the inferiors.
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	040576	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠INC≡≡R3≡≥	040604	005203				INC R3		;Count it.
≠MOV≡≡SP≡≡R1≡≥	040606	011601				MOV (SP),R1	;R1 ← event for the inferior EVT
≠JSR≡≡PC≡≡SPAWN≡≥	040610	004767	777516			JSR PC,SPAWN	;
≠MOV≡≡R0≡≡R2≡≥	040614	010002				MOV R0,R2	;R2 ← new process control block 
≥						;Set up the new environment
≠JSR≡≡PC≡≡NEWENV≡≥	040616	004767	774676			JSR PC,NEWENV	;R0 ← LOC[new environment]
≠MOV≡≡ENV≡≡R4≡≡SLINK≡≡R0≡≥	040622	016460	000006	000000		MOV ENV(R4),SLINK(R0)	;Not necessary to set up OLEV, etc.
≠MOV≡≡PDBR4≡≡R2≡≡R1≡≥	040630	016201	000036			MOV PDBR4(R2),R1;
≠MOV≡≡R0≡≡ENV≡≡R1≡≥	040634	010061	000006			MOV R0,ENV(R1)	;
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 130
	INTERP PAL[HAL,HE]	PAGE 11.2 	Table of interpreter instructions

≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	040640	016746	771044			      MOV SBEVT,-(SP)
≥	040644	104012				104012
≥					   .ENDC
≠INC≡≡LEV≡≡R1≡≥	040646	005261	000010			INC LEV(R1)	;
≤SCHEDU≡≥						SCHEDU R2,#INTERP,#1,#2;Cause the new process to be started, suspended
≤.ARG≡≥						  .ARG #2
≠.LIF≡≥						    .LIF NB #2
≠MOV≡≡SP≡≥	040652	012746	000002			      MOV #2,-(SP)
≤.ARG≡≥						  .ARG #1
≠.LIF≡≥						    .LIF NB #1
≠MOV≡≡SP≡≥	040656	012746	000001			      MOV #1,-(SP)
≤.ARG≡≥						  .ARG #INTERP
≠.LIF≡≥						    .LIF NB #INTERP
≠MOV≡≡INTERP≡≡SP≡≥	040662	012746	036016			      MOV #INTERP,-(SP)
≤.ARG≡≥						  .ARG R2
≠.LIF≡≥						    .LIF NB R2
≠MOV≡≡R2≡≡SP≡≥	040666	010246				      MOV R2,-(SP)
≥	040670	104016				104016
≠BR≡≥	040672	000736				BR  1$		;Go handle the next inferior.
≤BMPIPC≡≥					2$:	BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	040674	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠DEC≡≡R3≡≥	040702	005303			3$:	DEC R3		;Another wait to be done?
≠BMI≡≥	040704	100407				BMI 4$		;No, we are finished.
≤EVWAIT≡≥						EVWAIT (SP)	;Wait for an inferior to come back.
≤.ARG≡≥						  .ARG (SP)
≠.LIF≡≥						    .LIF NB (SP)
≠MOV≡≡SP≡≡SP≡≥	040706	011646				      MOV (SP),-(SP)
≥	040710	104010				104010
≠BCC≡≥	040712	103373				BCC 3$		;If all well, wait for the next one.
≤HALERR≡≥						HALERR SPRMES	;The event was killed!
≠MOV≡≡SPRMES≡≡SP≡≥	040714	012746	040734			MOV #SPRMES,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	040720	004777	753066			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤EVKIL≡≥					4$:	EVKIL (SP)+	;Kill the event now, remove from stack
≤.ARG≡≥						  .ARG (SP)+
≠.LIF≡≥						    .LIF NB (SP)+
≠MOV≡≡SP≡≡SP≡≥	040724	012646				      MOV (SP)+,-(SP)
≥	040726	104006				104006
≠MOV≡≡SP≡≡R3≡≥	040730	012603				MOV (SP)+,R3	;Restore R3
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	040732	000207				RTS PC		;Done
≤ASCIE≡≥					SPRMES: ASCIE /BAD RETURN FROM INFERIOR/
≠.ASCIZ≡≥	040734	   102		
≥	040735	   101		
≥	040736	   104		
≥	040737	   040		
≥	040740	   122		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 131
	INTERP PAL[HAL,HE]	PAGE 11.3 	Table of interpreter instructions

≥	040741	   105		
≥	040742	   124		
≥	040743	   125		
≥	040744	   122		
≥	040745	   116		
≥	040746	   040		
≥	040747	   106		
≥	040750	   122		
≥	040751	   117		
≥	040752	   115		
≥	040753	   040		
≥	040754	   111		
≥	040755	   116		
≥	040756	   106		
≥	040757	   105		
≥	040760	   122		
≥	040761	   111		
≥	040762	   117		
≥	040763	   122		
≥	040764	   000		
≥					       .ASCIZ /BAD RETURN FROM INFERIOR/
≠.EVEN≡≥		040766			       .EVEN
≥					
≥					
≥					TERMINATE:	
≠COMMEN≡≥				COMMENT ⊗ Interpreter routine, sometimes jumped to from other
≥					interpreter routines.  End this interpreter.  ⊗
≠MOV≡≡EVT≡≡R4≡≡R0≡≥	040766	016400	000016			MOV EVT(R4),R0	;R0 ← event to announce imminent demise
≠BEQ≡≥	040772	001402				BEQ 1$		;If there is one
≤EVSIG≡≥						EVSIG R0	;Announce that we are about to disappear.
≤.ARG≡≥						  .ARG R0
≠.LIF≡≥						    .LIF NB R0
≠MOV≡≡R0≡≡SP≡≥	040774	010046				      MOV R0,-(SP)
≥	040776	104012				104012
≠MOV≡≡STKBAS≡≡R4≡≡R0≡≥	041000	016400	000004		1$:	MOV STKBAS(R4),R0	;Reclaim interpreter stack
≠JSR≡≡PC≡≡RLFREE≡≥	041004	004767	767600			JSR PC,RLFREE	;
≠MOV≡≡PCB≡≡R4≡≡R0≡≥	041010	016400	000014			MOV PCB(R4),R0	;Reclaim process control block (may be dangerous)
≠JSR≡≡PC≡≡RLFREE≡≥	041014	004767	767570			JSR PC,RLFREE	;
≠MOV≡≡R4≡≡R0≡≥	041020	010400				MOV R4,R0	;Reclaim Interpreter Status Block
≠JSR≡≡PC≡≡RLFREE≡≥	041022	004767	767562			JSR PC,RLFREE	;
≤EVWAIT≡≥						EVWAIT INTEVT	;Enter critical region.
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	041026	016746	774256			      MOV INTEVT,-(SP)
≥	041032	104010				104010
≠MOV≡≡ISTBLK≡≡R0≡≥	041034	012700	063222			MOV #ISTBLK,R0	;The following unlinks this interpreter from the chain.
≠MOV≡≡R0≡≡R1≡≥	041040	010001			2$:	MOV R0,R1	;
≠MOV≡≡NXTINT≡≡R1≡≡R0≡≥	041042	016100	000002			MOV NXTINT(R1),R0;
≠CMP≡≡R0≡≡R4≡≥	041046	020004				CMP R0,R4	;Have we found ours yet?
≠BNE≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 132
	INTERP PAL[HAL,HE]	PAGE 11.4 	Table of interpreter instructions

≥	041050	001373				BNE 2$
≠MOV≡≡NXTINT≡≡R4≡≡NXTINT≡≡R1≡≥	041052	016461	000002	000002		MOV NXTINT(R4),NXTINT(R1); Yes. rechain.
≤EVSIG≡≥						EVSIG INTEVT	;Leave critical region.
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	041060	016746	774224			      MOV INTEVT,-(SP)
≥	041064	104012				104012
≤DISMIS≡≥						DISMIS		;Go away
≥	041066	104000				104000
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 133
	INTERP PAL[HAL,HE]	PAGE 12 	Table of interpreter instructions

≥					;Calculator routines: MEXP, MCLC, DCLC, ENDCLC;
≥					
≠COMMEN≡≥				COMMENT ⊗ Make an expression, put it in enviroment.  Arguments are
≥				the needed list (level-offset list, terminated by 0), the IPC
≥					(ablsolute address), and the offset. ⊗
≥					
≥					MEXP:	;Interpreter routine.
≥					
≠JSR≡≡PC≡≡NOGC≡≥	041070	004767	772162			JSR PC,NOGC	;Can't allow garbage collection til the needed
≥								;	list is stored away
≥								;Form the needed list
≠CLR≡≡SP≡≥	041074	005046				CLR -(SP)	;Start with null needed list on the stack
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	041076	017400	000000		1$:	MOV @IPC(R4),R0	;R0 ← the next needed level-offset
≠BEQ≡≥	041102	001421				BEQ 2$		;Any more?
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	041104	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	041112	004767	775144			JSR PC,GETARG	;R0 ← LOC[LOC[next needed graph node]]
≠MOV≡≡R0≡≡SP≡≥	041116	011046				MOV (R0),-(SP)	;Stack next needed graph node
≠JSR≡≡PC≡≡NEWCEL≡≥	041120	004767	017172			JSR PC,NEWCEL	;R0 ← LOC[new cell]
≠MOV≡≡SP≡≡CAR≡≡R0≡≥	041124	012660	000000			MOV (SP)+,CAR(R0)	;LOC[Needed graph node]
≠MOV≡≡SP≡≡CDR≡≡R0≡≥	041130	011660	000002			MOV (SP),CDR(R0);Link to rest of needed list
≠MOV≡≡R0≡≡SP≡≥	041134	010016				MOV R0,(SP)	;New needed list
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored (sort of)
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	041136	016746	770546			      MOV SBEVT,-(SP)
≥	041142	104012				104012
≥					   .ENDC
≠BR≡≥	041144	000754				BR 1$		;Repeat
≤BMPIPC≡≥					2$:	BMPIPC		;Bump IPC past the 0 at end of list
≠ADD≡≡IPC≡≡R4≡≥	041146	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠MOV≡≡SP≡≡R0≡≥	041154	012600				MOV (SP)+,R0	;R0 ← needed list
≥					
≠MOV≡≡IPC≡≡R4≡≡R1≡≥	041156	017401	000000			MOV @IPC(R4),R1	;R1 ← IPC
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	041162	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤CALL≡≥						CALL MAKEXP,<R4,R1,R0>	;R0 ← LOC[new expression node]
≠MOV≡≡RF≡≡SP≡≥	041170	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R4,R1,R0
≠.IRP≡≥						       .IRP II,<R4,R1,R0>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R4≡≡SP≡≥	041172	010446					MOV	R4,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡R1≡≡SP≡≥	041174	010146					MOV	R1,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡R0≡≡SP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 134
	INTERP PAL[HAL,HE]	PAGE 12.1 	Table of interpreter instructions

≥	041176	010046					MOV	R0,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006403					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	041200	012746	006403			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	041204	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡MAKEXP≡≥	041206	004767	020476			JSR	PC,MAKEXP		;Call the routine
≠MOV≡≡IPC≡≡R4≡≡R1≡≥	041212	017401	000000			MOV @IPC(R4),R1	;R1 ← offset
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	041216	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠BIC≡≡R1≡≥	041224	042701	177400			BIC #177400,R1	;Remove level info.
≠ADD≡≡ENV≡≡R4≡≡R1≡≥	041230	066401	000006			ADD ENV(R4),R1	;R0 ← Pointer into environment
≠MOV≡≡R0≡≡R1≡≥	041234	010011				MOV R0,(R1)	;Stow away pointer to expression node
≠JSR≡≡PC≡≡YESGC≡≥	041236	004767	772036			JSR PC,YESGC	;Garbage collection okay now
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	041242	000207				RTS PC		;Done
≥					
≥					MCLC:	;Interpreter routine.
≠COMMEN≡≥				COMMENT ⊗ Takes two arguments: the level-offset of the expression,
≥				and the level-offset of the variable for which this expression is to
≥					be a calculator.  ⊗
≥					
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	041244	017400	000000			MOV @IPC(R4),R0	;R0 ← Level-offset of expression
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	041250	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	041256	004767	775000			JSR PC,GETARG	;R0 ← LOC[LOC[exression node]]
≠MOV≡≡R0≡≡R2≡≥	041262	011002				MOV (R0),R2	;R2 ← LOC[expression node]
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	041264	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset of variable
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	041270	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	041276	004767	774760			JSR PC,GETARG	;R0 ← LOC[LOC[variable node]]
≤CALL≡≥						CALL ADDCLC,<(R0),R2>	;Do the linking
≠MOV≡≡RF≡≡SP≡≥	041302	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB (R0),R2
≠.IRP≡≥						       .IRP II,<(R0),R2>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R0≡≡SP≡≥	041304	011046					MOV	(R0),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡R2≡≡SP≡≥	041306	010246					MOV	R2,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	041310	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	041314	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡ADDCLC≡≥	041316	004767	020250			JSR	PC,ADDCLC		;Call the routine
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 135
	INTERP PAL[HAL,HE]	PAGE 12.2 	Table of interpreter instructions

≥	041322	000207				RTS PC		;Done
≥					
≥					DCLC:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Takes two arguments: the level-offset of the expression,
≥				and the level-offset of the variable from which this expression is to
≥					be removed as a calculator.  ⊗
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	041324	017400	000000			MOV @IPC(R4),R0	;R0 ← Level-offset of expression
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	041330	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	041336	004767	774720			JSR PC,GETARG	;R0 ← LOC[LOC[exression node]]
≠MOV≡≡R0≡≡R2≡≥	041342	011002				MOV (R0),R2	;R2 ← LOC[expression node]
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	041344	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset of variable
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	041350	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	041356	004767	774700			JSR PC,GETARG	;R0 ← LOC[LOC[variable node]]
≤CALL≡≥						CALL REMCLC,<(R0),R2>	;Do the unlinking
≠MOV≡≡RF≡≡SP≡≥	041362	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB (R0),R2
≠.IRP≡≥						       .IRP II,<(R0),R2>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R0≡≡SP≡≥	041364	011046					MOV	(R0),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡R2≡≡SP≡≥	041366	010246					MOV	R2,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	041370	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	041374	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡REMCLC≡≥	041376	004767	020506			JSR	PC,REMCLC		;Call the routine
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	041402	000207				RTS PC		;Done
≥					
≥					ENDCLC:	;Interpreter routine.
≠COMMEN≡≥				COMMENT ⊗ Called as last instruction in a calculator cell.  Returns
≥				via an RTS RF with the value from the top of the stack in R0.  Does
≥					not unlink anything. ⊗
≠MOV≡≡RF≡≡SP≡≥	041404	010506				MOV RF,SP 	;Reset the stack
≠TST≡≡SP≡≥	041406	005746				TST -(SP)	;
≠MOV≡≡R3≡≡R0≡≥	041410	012300				MOV (R3)+,R0	;Get the coveted value cell
≠RTS≡≡RF≡≥	041412	000205				RTS RF		;Will return to the calling point in EVLCLC.
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 136
	INTERP PAL[HAL,HE]	PAGE 13 	Table of interpreter instructions

≥					;Changer routines: MCHG, GTOLD, GTNEW
≥					
≠COMMEN≡≥				COMMENT ⊗ Make a changer for a graph node.  This involves several
≥				data: the target variable, specified as a level-offset pair, and the
≥				location of the changer code, (which is ordinary interpreter code
≥				which terminates with TERMINATE).  These data are passed as arguments
≥				to MCHG: target (level-offset), IPC (absolute address).  Recall that
≥				a changer cell looks like this:
≥				
≥					II==0
≥					XX  NXTCHG	;next changer cell in chain
≥					XX  CHGISB	;Points to interpreter status block to resolve addressing
≥					XX  CHGIPC	;the interpeter PC where the calculation starts
≥					CHGCSZ == II/2	;Size of changer cell, in words
≥					⊗
≥					
≥					MCHG:	;Interpreter routine.
≠MOV≡≡R2≡≡SP≡≥	041414	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡R3≡≡SP≡≥	041416	010346				MOV R3,-(SP)	;Save R3
≠MOV≡≡CHGCSZ≡≡R0≡≥	041420	012700	000003			MOV #CHGCSZ,R0	;Get room for a changer cell
≠JSR≡≡PC≡≡GTFREE≡≥	041424	004767	766616			JSR PC,GTFREE	;Note that we use large block allocation
≠MOV≡≡R0≡≡R3≡≥	041430	010003				MOV R0,R3	;R3 ← LOC[new changer cell]
≠MOV≡≡R4≡≡CHGISB≡≡R3≡≥	041432	010463	000002			MOV R4,CHGISB(R3)	;store away ISB
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	041436	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset pair.
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	041442	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	041450	004767	774606			JSR PC,GETARG	;R0 ← LOC[LOC[target graph node]]
≠MOV≡≡R0≡≡R2≡≥	041454	011002				MOV (R0),R2	;R2 ← LOC[target graph node]
≠MOV≡≡IPC≡≡R4≡≡CHGIPC≡≡R3≡≥	041456	017463	000000	000004		MOV @IPC(R4),CHGIPC(R3)	;store away target IPC
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	041464	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤CALL≡≥						CALL ADDCHG,<R2,R3>	;Do the final linking
≠MOV≡≡RF≡≡SP≡≥	041472	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R2,R3
≠.IRP≡≥						       .IRP II,<R2,R3>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R2≡≡SP≡≥	041474	010246					MOV	R2,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡R3≡≡SP≡≥	041476	010346					MOV	R3,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	041500	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	041504	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡ADDCHG≡≥	041506	004767	017220			JSR	PC,ADDCHG		;Call the routine
≠MOV≡≡SP≡≡R3≡≥	041512	012603				MOV (SP)+,R3	;Restore R3
≠MOV≡≡SP≡≡R2≡≥	041514	012602				MOV (SP)+,R2	;Restore R2
≤CCC≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 137
	INTERP PAL[HAL,HE]	PAGE 13.1 	Table of interpreter instructions

≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	041516	000207				RTS PC		;Done
≥					
≥					GTOLD:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Gets the OLD value that this changer (acting as an
≥					interpreter) has access to; puts it on the stack.  ⊗
≠MOV≡≡OLDV≡≡R4≡≡R3≡≥	041520	016443	000022			MOV OLDV(R4),-(R3)
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	041524	000207				RTS PC		;Done
≥					
≥					GTNEW:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Gets the NEW value that this changer (acting as an
≥					interpreter) has access to; puts it on the stack.  ⊗
≠MOV≡≡NEWV≡≡R4≡≡R3≡≥	041526	016443	000024			MOV NEWV(R4),-(R3)
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	041532	000207				RTS PC		;Done
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 138
	INTERP PAL[HAL,HE]	PAGE 14 	Table of interpreter instructions

≥					;Booleans: SLE,SLT,SGE,SGT,SEQ,SNE,AND,LOR,NOT
≥					
≥					COMP:	;auxiliary function used by SLE,SLT,SGE,SGT,SEQ,SNE
≠LDF≡≡R3≡≡AC0≡≥	041534	172433				LDF	@(R3)+,AC0	;Get first arg
≠CMPF≡≡R3≡≡AC0≡≥	041536	173433				CMPF	@(R3)+,AC0	;Compare it with second arg (1st-2nd)
≠JSR≡≡PC≡≡NOCMP≡≥	041540	004767	771612			JSR 	PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETSCA≡≥	041544	004767	774654			JSR	PC, GETSCA	;R0 ← -(R3) ← LOC[new_scalar]
≠MOV≡≡ONE≡≡R0≡≥	041550	016720	007556			MOV	ONE,(R0)+	;assume true (1.0)
≠CLR≡≡R0≡≥	041554	005010				CLR	(R0)
≠JSR≡≡PC≡≡YESCMP≡≥	041556	004767	771616			JSR 	PC,YESCMP	;OK to compact now
≠CFCC≡≠CFCC≡≥	041562	170000				CFCC			;copy condition flags from compare
≠RTS≡≡PC≡≥	041564	000207				RTS	PC		; & Return
≥					
≠JSR≡≡PC≡≡COMP≡≥	041566	004767	777742		SLT:	JSR	PC,COMP		;compare the args
≠BLT≡≥	041572	002402				BLT	1$		;if true then done
≠CLR≡≡R3≡≥	041574	005073	000000			CLR	@(R3)		;else set answer to false (0)
≠RTS≡≡PC≡≥	041600	000207			1$:	RTS	PC		; & return
≥					
≠JSR≡≡PC≡≡COMP≡≥	041602	004767	777726		SLE:	JSR	PC,COMP		;compare the args
≠BLE≡≥	041606	003402				BLE	1$		;if true then done
≠CLR≡≡R3≡≥	041610	005073	000000			CLR	@(R3)		;else set answer to false (0)
≠RTS≡≡PC≡≥	041614	000207			1$:	RTS	PC		; & return
≥					
≠JSR≡≡PC≡≡COMP≡≥	041616	004767	777712		SGT:	JSR	PC,COMP		;compare the args
≠BGT≡≥	041622	003002				BGT	1$		;if true then done
≠CLR≡≡R3≡≥	041624	005073	000000			CLR	@(R3)		;else set answer to false (0)
≠RTS≡≡PC≡≥	041630	000207			1$:	RTS	PC		; & return
≥					
≠JSR≡≡PC≡≡COMP≡≥	041632	004767	777676		SGE:	JSR	PC,COMP		;compare the args
≠BGE≡≥	041636	002002				BGE	1$		;if true then done
≠CLR≡≡R3≡≥	041640	005073	000000			CLR	@(R3)		;else set answer to false (0)
≠RTS≡≡PC≡≥	041644	000207			1$:	RTS	PC		; & return
≥					
≠JSR≡≡PC≡≡COMP≡≥	041646	004767	777662		SEQ:	JSR	PC,COMP		;compare the args
≠BEQ≡≥	041652	001402				BEQ	1$		;if true then done
≠CLR≡≡R3≡≥	041654	005073	000000			CLR	@(R3)		;else set answer to false (0)
≠RTS≡≡PC≡≥	041660	000207			1$:	RTS	PC		; & return
≥					
≠JSR≡≡PC≡≡COMP≡≥	041662	004767	777646		SNE:	JSR	PC,COMP		;compare the args
≠BNE≡≥	041666	001002				BNE	1$		;if true then done
≠CLR≡≡R3≡≥	041670	005073	000000			CLR	@(R3)		;else set answer to false (0)
≠RTS≡≡PC≡≥	041674	000207			1$:	RTS	PC		; & return
≥					
≠LDF≡≡R3≡≡AC0≡≥	041676	172433			AND:	LDF	@(R3)+,AC0	;Get first arg
≠LDF≡≡R3≡≡AC1≡≥	041700	172533				LDF	@(R3)+,AC1	;Get second arg (and set condition flags)
≠JSR≡≡PC≡≡NOCMP≡≥	041702	004767	771450			JSR 	PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETSCA≡≥	041706	004767	774512			JSR	PC, GETSCA	;R0 ← -(R3) ← LOC[new_scalar]
≠CLR≡≡R0≡≥	041712	005020				CLR	(R0)+		;assume false (0)
≠CLR≡≡R0≡≥	041714	005010				CLR	(R0)
≠JSR≡≡PC≡≡YESCMP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 139
	INTERP PAL[HAL,HE]	PAGE 14.1 	Table of interpreter instructions

≥	041716	004767	771456			JSR 	PC,YESCMP	;OK to compact now
≠CFCC≡≠CFCC≡≥	041722	170000				CFCC			;copy condition flags for 2nd arg
≠BEQ≡≥	041724	001406				BEQ	1$		;if it's false return false
≠TSTF≡≡AC0≡≥	041726	170500				TSTF	AC0		;else look at 1st arg
≠CFCC≡≠CFCC≡≥	041730	170000				CFCC
≠BEQ≡≥	041732	001403				BEQ	1$
≠MOV≡≡ONE≡≡R3≡≥	041734	016773	007372	000000		MOV	ONE,@(R3)	;if both args are true return true (1.0)
≠RTS≡≡PC≡≥	041742	000207			1$:	RTS	PC		; Return
≥					
≠LDF≡≡R3≡≡AC0≡≥	041744	172433			LOR:	LDF	@(R3)+,AC0	;Get first arg
≠LDF≡≡R3≡≡AC1≡≥	041746	172533				LDF	@(R3)+,AC1	;Get second arg (and set condition flags)
≠JSR≡≡PC≡≡NOCMP≡≥	041750	004767	771402			JSR 	PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETSCA≡≥	041754	004767	774444			JSR	PC, GETSCA	;R0 ← -(R3) ← LOC[new_scalar]
≠MOV≡≡ONE≡≡R0≡≥	041760	016720	007346			MOV	ONE,(R0)+	;assume true (1.0)
≠CLR≡≡R0≡≥	041764	005010				CLR	(R0)
≠JSR≡≡PC≡≡YESCMP≡≥	041766	004767	771406			JSR 	PC,YESCMP	;OK to compact now
≠CFCC≡≠CFCC≡≥	041772	170000				CFCC			;copy condition flags from compare
≠BNE≡≥	041774	001005				BNE	1$		;if it's true return true
≠TSTF≡≡AC0≡≥	041776	170500				TSTF	AC0		;else look at 1st arg
≠CFCC≡≠CFCC≡≥	042000	170000				CFCC
≠BNE≡≥	042002	001002				BNE	1$
≠CLR≡≡R3≡≥	042004	005073	000000			CLR	@(R3)		;if both args are false return false (0)
≠RTS≡≡PC≡≥	042010	000207			1$:	RTS	PC		; Return
≥					
≠LDF≡≡R3≡≡AC0≡≥	042012	172433			NOT:	LDF	@(R3)+,AC0	;Get arg (and set condition flags)
≠JSR≡≡PC≡≡NOCMP≡≥	042014	004767	771336			JSR 	PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETSCA≡≥	042020	004767	774400			JSR	PC, GETSCA	;R0 ← -(R3) ← LOC[new_scalar]
≠CLR≡≡R0≡≥	042024	005020				CLR	(R0)+		;assume false (0)
≠CLR≡≡R0≡≥	042026	005010				CLR	(R0)
≠JSR≡≡PC≡≡YESCMP≡≥	042030	004767	771344			JSR 	PC,YESCMP	;OK to compact now
≠CFCC≡≠CFCC≡≥	042034	170000				CFCC			;copy condition flags for arg
≠BNE≡≥	042036	001003				BNE	1$		;if it's false return true
≠MOV≡≡ONE≡≡R3≡≥	042040	016773	007266	000000		MOV	ONE,@(R3)	; else return true
≠RTS≡≡PC≡≥	042046	000207			1$:	RTS	PC		; Return
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 140
	INTERP PAL[HAL,HE]	PAGE 15 	Table of interpreter instructions

≥					;return scalars: SADD, SSUB, SMUL, SDIV, SNEG, VDOT, PVDOT, VMAG, SSBRTN
≥					
≠COMMEN≡≥				COMMENT ⊗ All timings are averages of 1000 runs.  They take into
≥				account the cost of the RTS but not the JSR.  It is assumed that
≥				GETSCA and GETVEC take no time.  All routines on this page are
≥					interpreter routines.  ⊗
≥					
≥					;30 microseconds
≥					SADD:	;Scalar ← Scalar + Scalar
≠LDF≡≡R3≡≡AC0≡≥	042050	172433				LDF @(R3)+,AC0	;AC0 ← arg 2
≠ADDF≡≡R3≡≡AC0≡≥	042052	172033				ADDF @(R3)+,AC0	;AC0 ← arg2 + arg1
≠JSR≡≡PC≡≡GETSCA≡≥	042054	004767	774344			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	042060	174073	000000			STF AC0,@(R3)	;Store result
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042064	000207				RTS PC		;Done
≥					
≥					SSUB:	;Scalar ← Scalar - Scalar
≠LDF≡≡R3≡≡AC0≡≥	042066	172473	000002			LDF @2(R3),AC0	;AC0 ← arg 1
≠SUBF≡≡R3≡≡AC0≡≥	042072	173033				SUBF @(R3)+,AC0	;AC0 ← arg1 - arg2
≠TST≡≡R3≡≥	042074	005723				TST (R3)+	;Move past first argument
≠JSR≡≡PC≡≡GETSCA≡≥	042076	004767	774322			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	042102	174073	000000			STF AC0,@(R3)	;Store result
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042106	000207				RTS PC		;Done
≥					
≥					;30 microseconds
≥					SMUL:	;Scalar ← scalar * scalar
≠LDF≡≡R3≡≡AC0≡≥	042110	172433				LDF @(R3)+,AC0	;AC0 ← arg 2
≠MULF≡≡R3≡≡AC0≡≥	042112	171033				MULF @(R3)+,AC0	;AC0 ← arg2 * arg1
≠JSR≡≡PC≡≡GETSCA≡≥	042114	004767	774304			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	042120	174073	000000			STF AC0,@(R3)	;Store result
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042124	000207				RTS PC		;Done
≥					
≥					;33 microseconds
≥					SDIV:	;Scalar ← Scalar / Scalar
≠LDF≡≡R3≡≡AC1≡≥	042126	172533				LDF @(R3)+,AC1	;AC1 ← arg 2
≠LDF≡≡R3≡≡AC0≡≥	042130	172433				LDF @(R3)+,AC0	;AC0 ← arg 1
≠DIVF≡≡AC1≡≡AC0≡≥	042132	174401				DIVF AC1,AC0	;AC0 ← arg1 / arg2
≠JSR≡≡PC≡≡GETSCA≡≥	042134	004767	774264			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	042140	174073	000000			STF AC0,@(R3)	;Store result
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042144	000207				RTS PC		;Done
≥					
≥					;26 microseconds
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 141
	INTERP PAL[HAL,HE]	PAGE 15.1 	Table of interpreter instructions

≥					SNEG:	;Scalar ← -Scalar
≠LDF≡≡R3≡≡AC0≡≥	042146	172433				LDF @(R3)+,AC0	;AC0 ← arg
≠NEGF≡≡AC0≡≥	042150	170700				NEGF AC0	;AC0 ← -arg
≠JSR≡≡PC≡≡GETSCA≡≥	042152	004767	774246			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	042156	174073	000000			STF AC0,@(R3)	;Store result
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042162	000207				RTS PC		;Done
≥					
≥					;96 -- 116 microseconds
≥					VDOT:	;Scalar ← Vector dot Vector
≥						;S ← (X1X2 + Y1Y2 + Z1Z2) / W1W2
≠MOV≡≡R2≡≡SP≡≥	042164	010246				MOV R2,-(SP)	;Save R2.
≠JSR≡≡PC≡≡NOCMP≡≥	042166	004767	771164			JSR PC,NOCMP	;Don't compact for a bit
≠MOV≡≡R3≡≡R1≡≥	042172	012301				MOV (R3)+,R1	;R1 ← LOC[arg 2]
≠MOV≡≡R3≡≡R0≡≥	042174	012300				MOV (R3)+,R0	;R0 ← LOC[arg 1]
≠CLRF≡≡AC0≡≥	042176	170400				CLRF AC0	;AC0 ← 0.  Running total
≠MOV≡≡R2≡≥	042200	012702	000003			MOV #3,R2	;R2 ← 3:  Length of vector
≠LDF≡≡R0≡≡AC1≡≥	042204	172520			1$:	LDF (R0)+,AC1	;Form sum of products of first 3 terms
≠MULF≡≡R1≡≡AC1≡≥	042206	171121				MULF (R1)+,AC1	;
≠ADDF≡≡AC1≡≡AC0≡≥	042210	172001				ADDF AC1,AC0	;
≠SOB≡≡R2≡≥	042212	077204				SOB R2,1$	;Loop until all 3 fields done.
≠DIVF≡≡R0≡≡AC0≡≥	042214	174410				DIVF (R0),AC0	;Divide by W1
≠DIVF≡≡R1≡≡AC0≡≥	042216	174411				DIVF (R1),AC0	;Divide by W2.  AC0 now has answer.
≠JSR≡≡PC≡≡YESCMP≡≥	042220	004767	771154			JSR PC,YESCMP	;OK to compact now
≠JSR≡≡PC≡≡GETSCA≡≥	042224	004767	774174			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	042230	174073	000000			STF AC0,@(R3)	;Store result
≠MOV≡≡SP≡≡R2≡≥	042234	012602				MOV (SP)+,R2	;Restore R2
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042236	000207				RTS PC		;Done
≥					
≥					;103 -- 116 microseconds
≥					PVDOT:	;Scalar ← Plane dot Vector
≥						;S ← X1X2 + Y1Y2 + Z1Z2 + W1W2
≠MOV≡≡R2≡≡SP≡≥	042240	010246				MOV R2,-(SP)	;Save R2.
≠JSR≡≡PC≡≡NOCMP≡≥	042242	004767	771110			JSR PC,NOCMP	;Don't compact for a bit
≠MOV≡≡R3≡≡R1≡≥	042246	012301				MOV (R3)+,R1	;R1 ← LOC[arg 2]
≠MOV≡≡R3≡≡R0≡≥	042250	012300				MOV (R3)+,R0	;R0 ← LOC[arg 1]
≠CLRF≡≡AC0≡≥	042252	170400				CLRF AC0	;AC0 ← 0.  Running total
≠MOV≡≡R2≡≥	042254	012702	000004			MOV #4,R2	;R2 ← 4:  Length of vector and weight
≠LDF≡≡R0≡≡AC1≡≥	042260	172520			1$:	LDF (R0)+,AC1	;Form sum of products of all 4 terms
≠MULF≡≡R1≡≡AC1≡≥	042262	171121				MULF (R1)+,AC1	;
≠ADDF≡≡AC1≡≡AC0≡≥	042264	172001				ADDF AC1,AC0	;
≠SOB≡≡R2≡≥	042266	077204				SOB R2,1$	;Loop until all 3 fields done.
≠JSR≡≡PC≡≡YESCMP≡≥	042270	004767	771104			JSR PC,YESCMP	;OK to compact now
≠JSR≡≡PC≡≡GETSCA≡≥	042274	004767	774124			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	042300	174073	000000			STF AC0,@(R3)	;Store result
≠MOV≡≡SP≡≡R2≡≥	042304	012602				MOV (SP)+,R2	;Restore R2
≤CCC≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 142
	INTERP PAL[HAL,HE]	PAGE 15.2 	Table of interpreter instructions

≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042306	000207				RTS PC		;Done
≥					
≥					;199 -- 207 microseconds
≥					VMAGN:	;Scalar ← Norm (vector)
≥						;S ← SQRT(XX + YY+ ZZ) / W
≠JSR≡≡PC≡≡NOCMP≡≥	042310	004767	771042			JSR PC,NOCMP	;Don't compact for a bit
≠MOV≡≡R3≡≡R1≡≥	042314	012301				MOV (R3)+,R1	;R1 ← LOC[arg]
≠LDF≡≡R1≡≡AC0≡≥	042316	172421				LDF (R1)+,AC0	;AC0 ← X
≠MULF≡≡AC0≡≡AC0≡≥	042320	171000				MULF AC0,AC0	;AC0 ← XX
≠LDF≡≡R1≡≡AC1≡≥	042322	172521				LDF (R1)+,AC1	;AC1 ← Y
≠MULF≡≡AC1≡≡AC1≡≥	042324	171101				MULF AC1,AC1	;AC1 ← YY
≠ADDF≡≡AC1≡≡AC0≡≥	042326	172001				ADDF AC1,AC0	;AC0 ← XX + YY
≠LDF≡≡R1≡≡AC1≡≥	042330	172521				LDF (R1)+,AC1	;AC1 ← Z
≠MULF≡≡AC1≡≡AC1≡≥	042332	171101				MULF AC1,AC1	;AC1 ← ZZ
≠ADDF≡≡AC1≡≡AC0≡≥	042334	172001				ADDF AC1,AC0	;AC0 ← XX + YY + ZZ
≠MOV≡≡R1≡≡SP≡≥	042336	010146				MOV R1,-(SP)	;Push LOC[W] onto system stack, to save across SQRTF
≠JSR≡≡PC≡≡LSQRTF≡≥	042340	004777	751472			JSR PC,@LSQRTF	;AC0 ← SQRT(XX + YY + ZZ)
≠DIVF≡≡SP≡≡AC0≡≥	042344	174436				DIVF @(SP)+,AC0	;AC0 ← AC0 / W
≠JSR≡≡PC≡≡YESCMP≡≥	042346	004767	771026			JSR PC,YESCMP	;OK to compact now
≠JSR≡≡PC≡≡GETSCA≡≥	042352	004767	774046			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	042356	174073	000000			STF AC0,@(R3)	;Store answer
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042362	000207				RTS PC		;Done
≥					
≥					SSBRTN:	;Call a routine.
≠LDF≡≡R3≡≡AC0≡≥	042364	172433				LDF @(R3)+,AC0	;AC0 ← arg
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	042366	017400	000000			MOV @IPC(R4),R0	;R0 ← which routine (a small number)
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	042372	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠ASL≡≡R0≡≥	042400	006300				ASL R0		;Double (words → bytes)
≠BLE≡≥	042402	003412				BLE 1$		;Too small.
≠CMP≡≡R0≡≡SBLSIZ≡≥	042404	020027	000004			CMP R0,#SBLSIZ	;Too large?
≠BGE≡≥	042410	002007				BGE 1$		;Yes
≠JSR≡≡PC≡≡SBRLST≡≡R0≡≥	042412	004770	042466			JSR PC,@SBRLST(R0)	;Call a routine.  AC0 ← answer.
≠JSR≡≡PC≡≡GETSCA≡≥	042416	004767	774002			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	042422	174073	000000			STF AC0,@(R3)	;Store answer
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042426	000207				RTS PC		;Done
≤HALERR≡≥					1$:	HALERR SSBRMS	;Complain
≠MOV≡≡SSBRMS≡≡SP≡≥	042430	012746	042442			MOV #SSBRMS,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	042434	004777	751352			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤SCC≡≥						SCC		;Set condition code
≥					;	MOV #2,R0	;Set condition code.  Not used right now. (maybe use TST PC)
≠RTS≡≡PC≡≥	042440	000207				RTS PC		;Done
≤ASCIE≡≥					SSBRMS:	ASCIE </NO SUCH SUBROUTINE/>
≠.ASCIZ≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 143
	INTERP PAL[HAL,HE]	PAGE 15.3 	Table of interpreter instructions

≥	042442	   116		
≥	042443	   117		
≥	042444	   040		
≥	042445	   123		
≥	042446	   125		
≥	042447	   103		
≥	042450	   110		
≥	042451	   040		
≥	042452	   123		
≥	042453	   125		
≥	042454	   102		
≥	042455	   122		
≥	042456	   117		
≥	042457	   125		
≥	042460	   124		
≥	042461	   111		
≥	042462	   116		
≥	042463	   105		
≥	042464	   000		
≥					       .ASCIZ /NO SUCH SUBROUTINE/
≠.EVEN≡≥		042466			       .EVEN
≥					
≥					SBRLST:	;List of legal subroutines
≥	042466	000000				0		;Illegal
≡SQRT≡≡SQRT≡≥	042470	042472				SQRT		;The only one right now. #1
≡SBRLST≡≡SBLSIZ≠≥		000004			SBLSIZ == .-SBRLST	;The size of the list (bytes)
≥					
≠JMP≡≡LSQRTF≡≥	042472	000177	751340		SQRT:	JMP @LSQRTF	;Let it do the returning
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 144
	INTERP PAL[HAL,HE]	PAGE 16 	Table of interpreter instructions

≥					;Vector utilities:  UNITV, CROSV
≥					
≥					;281 -- 286 microseconds  
≥					UNITV:	;Vector ← V / Norm(V)
≥						;S ← SQRT(XX + YY+ ZZ)
≠JSR≡≡PC≡≡NOCMP≡≥	042476	004767	770654			JSR PC,NOCMP	;Don't compact for a bit
≠MOV≡≡R3≡≡R1≡≥	042502	011301				MOV (R3),R1	;R1 ← LOC[arg]
≠LDF≡≡R1≡≡AC0≡≥	042504	172421				LDF (R1)+,AC0	;AC0 ← X
≠MULF≡≡AC0≡≡AC0≡≥	042506	171000				MULF AC0,AC0	;AC0 ← XX
≠LDF≡≡R1≡≡AC1≡≥	042510	172521				LDF (R1)+,AC1	;AC1 ← Y
≠MULF≡≡AC1≡≡AC1≡≥	042512	171101				MULF AC1,AC1	;AC1 ← YY
≠ADDF≡≡AC1≡≡AC0≡≥	042514	172001				ADDF AC1,AC0	;AC0 ← XX + YY
≠LDF≡≡R1≡≡AC1≡≥	042516	172521				LDF (R1)+,AC1	;AC1 ← Z
≠MULF≡≡AC1≡≡AC1≡≥	042520	171101				MULF AC1,AC1	;AC1 ← ZZ
≠ADDF≡≡AC1≡≡AC0≡≥	042522	172001				ADDF AC1,AC0	;AC0 ← XX + YY + ZZ
≠JSR≡≡PC≡≡LSQRTF≡≥	042524	004777	751306			JSR PC,@LSQRTF	;AC0 ← SQRT(XX + YY + ZZ)
≠JSR≡≡PC≡≡GETVEC≡≥	042530	004767	773712			JSR PC,GETVEC	;R0 ← -(R3) ← LOC[new vector block]
≠MOV≡≡R3≡≡R1≡≥	042534	016301	000002			MOV 2(R3),R1	;R1 ← LOC[old vector]
≠MOV≡≡R2≡≥	042540	012702	000003			MOV #3,R2	;R2 ← count of fields
≠LDF≡≡R1≡≡AC1≡≥	042544	172521			1$:	LDF (R1)+,AC1	;AC1 ← field of vector
≠DIVF≡≡AC0≡≡AC1≡≥	042546	174500				DIVF AC0,AC1	;divide by norm
≠STF≡≡AC1≡≡R0≡≥	042550	174120				STF AC1,(R0)+	;Store result
≠SOB≡≡R2≡≥	042552	077204				SOB R2,1$	;Loop until done
≠MOV≡≡ONE≡≡R0≡≥	042554	016720	006552			MOV ONE,(R0)+	;Set W to 1
≠CLR≡≡R0≡≥	042560	005010				CLR (R0)	;   (two words long)
≠MOV≡≡R3≡≡R3≡≥	042562	012313				MOV (R3)+,(R3)	;Fix-up stack
≠JSR≡≡PC≡≡YESCMP≡≥	042564	004767	770610			JSR PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042570	000207				RTS PC		;Done
≥					
≠COMMEN≡≥				COMMENT ⊗  These are not  currently being used
≥				
≥				;172 -- 184 microseconds  
≥				CROSV:	;Vector ← Vector cross Vector
≥					;X ← Y1Z2 - Y2Z1
≥					;Y ← X2Z1 - X1Z2
≥					;Z ← X1Y2 - X2Y1
≥					;W ← W1W2
≥					;AC0, 1, 2, 3, 4, 5 are garbaged by this routine.
≥					JSR PC,NOCMP	;Don't compact for a bit
≥					JSR PC,GETVEC	;R0 ← -(R3) ← LOC[new vector block]
≥					MOV 2(R3),R2	;R2 ← LOC[arg 2]
≥					MOV 4(R3),R1	;R1 ← LOC[arg 1].  Must not pop R3 stack yet!
≥					LDF 14(R1),AC0	;AC0 ← W1
≥					MULF 14(R2),AC0	;AC0 ← W1W2
≥					STF AC0,14(R0)	;Store AC0 → W
≥					LDF 4(R1),AC0	;AC0 ← Y1
≥					LDF (R2),AC1	;AC1 ← X2
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 145
	INTERP PAL[HAL,HE]	PAGE 16.1 	Table of interpreter instructions

≥					LDF 4(R2),AC2	;AC2 ← Y2
≥					LDF (R1),AC3	;AC3 ← X1
≥					STF AC3,AC4	;AC4 ← X1
≥					STF AC0,AC5	;AC5 ← Y1
≥					MULF AC2,AC3	;AC3 ← X1Y2
≥					MULF AC1,AC0	;AC0 ← X2Y1
≥					SUBF AC0,AC3	;AC3 ← X1Y2 - X2Y1
≥					STF AC3,10(R0)	;Z ← AC3
≥					LDF 10(R2),AC0	;AC0 ← Z2
≥					LDF 10(R1),AC3	;AC3 ← Z1
≥					MULF AC4,AC0	;AC0 ← X1Z2
≥					MULF AC3,AC1	;AC1 ← X2Z1
≥					SUBF AC0,AC1	;AC1 ← X2Z1 - X1Z2
≥					STF AC1,4(R0)	;Y ← AC1
≥					LDF 10(R2),AC0	;AC0 ← Z2
≥					MULF AC5,AC0	;AC0 ← Y1Z2
≥					MULF AC2,AC3	;AC3 ← Y2Z1
≥					SUBF AC3,AC0	;AC0 ← Y1Z2 - Y2Z1
≥					STF AC0,(R0)	;X ← AC0
≥					MOV (R3)+,2(R3) ;Put result cell where first arg was 
≥					TST (R3)+	; & fix-up stack
≥					JSR PC,YESCMP	;OK to compact now
≥					CCC		;Clear condition code
≥					RTS PC		;Done
≥				
≥					⊗ END OF COMMENTED-OUT PROCEDURES.
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 146
	INTERP PAL[HAL,HE]	PAGE 17 	Table of interpreter instructions

≥					;TRANS extraction routines: TPOS, TORIEN, TAXIS, TMAGN
≥					
≥					TPOS:	;Extracts the position part of a TRANS (last column)
≠JSR≡≡PC≡≡NOCMP≡≥	042572	004767	770560			JSR 	PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETVEC≡≥	042576	004767	773644			JSR	PC,GETVEC	;R0 ← -(R3) ← LOC[New Vector]
≠MOV≡≡R3≡≡R1≡≥	042602	016301	000002			MOV	2(R3),R1	;R1 ← LOC[TRANS]
≠ADD≡≡R1≡≥	042606	062701	000044			ADD	#44,R1		;R1 ← LOC [last column of TRANS]
≠MOV≡≡R2≡≥	042612	012702	000006			MOV	#6,R2		;Three 2-word components to move
≠MOV≡≡R1≡≡R0≡≥	042616	012120			1$:	MOV	(R1)+,(R0)+	;Copy it
≠SOB≡≡R2≡≥	042620	077202				SOB	R2,1$
≠MOV≡≡ONE≡≡R0≡≥	042622	016720	006504			MOV	ONE,(R0)+	;Stick in the scale factor
≠CLR≡≡R0≡≥	042626	005010				CLR	(R0)
≠MOV≡≡R3≡≡R3≡≥	042630	012313				MOV	(R3)+,(R3)	;Fix-up stack
≠JSR≡≡PC≡≡YESCMP≡≥	042632	004767	770542			JSR 	PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC			;Clear condition codes
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042636	000207				RTS	PC		; & Return
≥					
≥					TORIEN:	;Extracts the rotation part of a TRANS
≠JSR≡≡PC≡≡NOCMP≡≥	042640	004767	770512			JSR 	PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETTRN≡≥	042644	004767	773620			JSR	PC,GETTRN	;R0 ← -(R3) ← LOC[New TRANS]
≠MOV≡≡R3≡≡R1≡≥	042650	016301	000002			MOV	2(R3),R1	;R1 ← LOC[TRANS]
≠MOV≡≡R2≡≥	042654	012702	000022			MOV	#22,R2		;Three columns to do, three 2-word #'s/col
≠MOV≡≡R1≡≡R0≡≥	042660	012120			1$:	MOV	(R1)+,(R0)+	;Copy the ROTN
≠SOB≡≡R2≡≥	042662	077202				SOB	R2,1$
≠MOV≡≡R2≡≥	042664	012702	000006			MOV	#6,R2
≠CLR≡≡R0≡≥	042670	005020			2$:	CLR	(R0)+		;Set up last column, three 0's
≠SOB≡≡R2≡≥	042672	077202				SOB	R2,2$
≠MOV≡≡R3≡≡R3≡≥	042674	012313				MOV	(R3)+,(R3)	;Fix-up stack
≠JSR≡≡PC≡≡YESCMP≡≥	042676	004767	770476			JSR 	PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC			;Clear cond codes
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042702	000207				RTS	PC		; & Return
≥					
≥					;TAXIS & TANGLE  routines to extract the axis vector and angle of rotation
≥					;		 given a rotation (trans);
≥					
≥					;Define some constants
≥					
≠.WORD≡≥	042704	040400		
≥	042706	000000			TWO:	.WORD	40400, 0	;2
≠.WORD≡≥	042710	040023		
≥	042712	072274			CTHIRD:	.WORD	40023, 72274	;Square root of 1/3 (0.576)
≠.WORD≡≥	042714	040200		
≥	042716	001507			C1001:	.WORD	40200, 1507	;1.0001
≠.WORD≡≥	042720	034721		
≥	042722	133427			C0001:	.WORD	34721, 133427	;0.0001
≥					
≠JSR≡≡PC≡≡TAXAN≡≥	042724	004767	000244		TAXIS:	JSR	PC,TAXAN	;Get vector components in AC3,AC4 & AC5
≠TST≡≡R3≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 147
	INTERP PAL[HAL,HE]	PAGE 17.1 	Table of interpreter instructions

≥	042730	005723				TST	(R3)+		;Fix stack
≠JSR≡≡PC≡≡GETVEC≡≥	042732	004767	773510			JSR	PC,GETVEC	;Get a new vector to store results
≠STF≡≡AC3≡≡R0≡≥	042736	174320				STF	AC3,(R0)+
≠LDF≡≡AC4≡≡AC0≡≥	042740	172404				LDF	AC4,AC0
≠STF≡≡AC0≡≡R0≡≥	042742	174020				STF	AC0,(R0)+	;Store X,Y & Z components
≠LDF≡≡AC5≡≡AC0≡≥	042744	172405				LDF	AC5,AC0
≠STF≡≡AC0≡≡R0≡≥	042746	174020				STF	AC0,(R0)+
≠MOV≡≡ONE≡≡R0≡≥	042750	016720	006356			MOV	ONE,(R0)+	;Store scale factor of 1
≠CLR≡≡R0≡≥	042754	005010				CLR	(R0)
≠JSR≡≡PC≡≡YESCMP≡≥	042756	004767	770416			JSR 	PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC			;Clear condition codes
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	042762	000207				RTS	PC		; & Return
≥					
≠JSR≡≡PC≡≡TAXAN≡≥	042764	004767	000204		TMAGN:	JSR	PC,TAXAN	;Get COS(angle) in AC0, vector components in AC 3-5
≠STF≡≡AC3≡≡SP≡≥	042770	174346				STF	AC3,-(SP)	;Store X component
≠JSR≡≡PC≡≡LACOS≡≥	042772	004777	751044			JSR	PC,@LACOS	;Compute angle in AC0
≠LDF≡≡SP≡≡AC3≡≥	042776	172726				LDF	(SP)+,AC3	;Retrieve X
≠LDF≡≡CTHIRD≡≡AC1≡≥	043000	172567	777704			LDF	CTHIRD,AC1	;Square root of 1/3
≠LDF≡≡AC3≡≡AC2≡≥	043004	172603				LDF	AC3,AC2		;Get X
≠ABSF≡≡AC2≡≥	043006	170602				ABSF	AC2
≠CMPF≡≡AC2≡≡AC1≡≥	043010	173502				CMPF	AC2,AC1		;ABS(X)-SQRT(1/3)
≠CFCC≡≠CFCC≡≥	043012	170000				CFCC			;Copy FPP cond codes into CPU cond codes
≠BLT≡≥	043014	002406				BLT	1$
≠LDF≡≡R2≡≡AC1≡≥	043016	172562	000034			LDF	34(R2),AC1	;Get (2,3)
≠SUBF≡≡R2≡≡AC1≡≥	043022	173162	000024			SUBF	24(R2),AC1	;(2,3) - (3,2)
≠MULF≡≡AC3≡≡AC1≡≥	043026	171103				MULF	AC3,AC1		;Get sign of SIN(angle)
≠BR≡≥	043030	000433				BR	4$
≠LDF≡≡AC4≡≡AC2≡≥	043032	172604			1$:	LDF	AC4,AC2		;Get Y
≠ABSF≡≡AC2≡≥	043034	170602				ABSF	AC2
≠CMPF≡≡AC2≡≡AC1≡≥	043036	173502				CMPF	AC2,AC1		;ABS(Y)-SQRT(1/3)
≠CFCC≡≠CFCC≡≥	043040	170000				CFCC			;Copy FPP cond codes into CPU cond codes
≠BLT≡≥	043042	002406				BLT	2$
≠LDF≡≡R2≡≡AC1≡≥	043044	172562	000010			LDF	10(R2),AC1	;Get (3,1)
≠SUBF≡≡R2≡≡AC1≡≥	043050	173162	000030			SUBF	30(R2),AC1	;(3,1) - (1,3)
≠MULF≡≡AC4≡≡AC1≡≥	043054	171104				MULF	AC4,AC1		;Get sign of SIN(angle)
≠BR≡≥	043056	000420				BR	4$
≠LDF≡≡AC5≡≡AC2≡≥	043060	172605			2$:	LDF	AC5,AC2		;Get Z
≠ABSF≡≡AC2≡≥	043062	170602				ABSF	AC2
≠CMPF≡≡AC2≡≡AC1≡≥	043064	173502				CMPF	AC2,AC1		;ABS(Z)-SQRT(1/3)
≠CFCC≡≠CFCC≡≥	043066	170000				CFCC			;Copy FPP cond codes into CPU cond codes
≠BLT≡≥	043070	002406				BLT	3$
≠LDF≡≡R2≡≡AC1≡≥	043072	172562	000014			LDF	14(R2),AC1	;Get (1,2)
≠SUBF≡≡R2≡≡AC1≡≥	043076	173162	000004			SUBF	4(R2),AC1	;(1,2) - (2,1)
≠MULF≡≡AC5≡≡AC1≡≥	043102	171105				MULF	AC5,AC1		;Get sign of SIN(angle)
≠BR≡≥	043104	000405				BR	4$
≤HALERR≡≥					3$:	HALERR	TMAGMS		;Complain
≠MOV≡≡TMAGMS≡≡SP≡≥	043106	012746	043146			MOV #TMAGMS,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	043112	004777	750674			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠CLRF≡≡AC0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 148
	INTERP PAL[HAL,HE]	PAGE 17.2 	Table of interpreter instructions

≥	043116	170400				CLRF	AC0		;& return NILROT
≠CFCC≡≠CFCC≡≥	043120	170000			4$:	CFCC
≠BLT≡≥	043122	002401				BLT	5$
≠NEGF≡≡AC0≡≥	043124	170700				NEGF	AC0		;If SIN(angle) > 0 then negate angle
≠TST≡≡R3≡≥	043126	005723			5$:	TST	(R3)+		;Clean up stack
≠JSR≡≡PC≡≡YESCMP≡≥	043130	004767	770244			JSR 	PC,YESCMP	;OK to compact now
≠JSR≡≡PC≡≡GETSCA≡≥	043134	004767	773264			JSR	PC,GETSCA	;Get a scalar
≠STF≡≡AC0≡≡R3≡≥	043140	174073	000000			STF	AC0,@(R3)	;Store the angle of rotation
≤CCC≡≥						CCC			;Clear condition codes
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	043144	000207				RTS	PC		; & Return
≥					
≤ASCIE≡≥					TMAGMS:	ASCIE	</ROTATION STRANGENESS/>
≠.ASCIZ≡≥	043146	   122		
≥	043147	   117		
≥	043150	   124		
≥	043151	   101		
≥	043152	   124		
≥	043153	   111		
≥	043154	   117		
≥	043155	   116		
≥	043156	   040		
≥	043157	   123		
≥	043160	   124		
≥	043161	   122		
≥	043162	   101		
≥	043163	   116		
≥	043164	   107		
≥	043165	   105		
≥	043166	   116		
≥	043167	   105		
≥	043170	   123		
≥	043171	   123		
≥	043172	   000		
≥					       .ASCIZ /ROTATION STRANGENESS/
≠.EVEN≡≥		043174			       .EVEN
≥					
≥					TAXAN:	;Code common to both TAXIS & TMAGN
≠JSR≡≡PC≡≡NOCMP≡≥	043174	004767	770156			JSR 	PC,NOCMP	;Don't compact for a bit
≠MOV≡≡R3≡≡R2≡≥	043200	011302				MOV	(R3),R2		;R2 points to the ROT
≠LDF≡≡R2≡≡AC0≡≥	043202	172412				LDF	(R2),AC0	;(1,1)
≠ADDF≡≡R2≡≡AC0≡≥	043204	172062	000020			ADDF	20(R2),AC0	;(2,2)
≠ADDF≡≡R2≡≡AC0≡≥	043210	172062	000040			ADDF	40(R2),AC0	;AC0 ← [(1,1)+(2,2)+(3,3)-1]/2 = COS(angle)
≠SUBF≡≡ONE≡≡AC0≡≥	043214	173067	006112			SUBF	ONE,AC0
≠STF≡≡AC0≡≡AC3≡≥	043220	174003				STF	AC0,AC3		;we'll use this later
≠DIVF≡≡TWO≡≡AC0≡≥	043222	174467	777456			DIVF	TWO,AC0
≠STF≡≡AC0≡≡AC1≡≥	043226	174001				STF	AC0,AC1		;Make a copy
≠ABSF≡≡AC1≡≥	043230	170601				ABSF	AC1
≠CMPF≡≡C1001≡≡AC1≡≥	043232	173567	777456			CMPF	C1001,AC1	;If ABS(COS(angle)) > 1.0001 return the NILROT
≠CFCC≡≠CFCC≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 149
	INTERP PAL[HAL,HE]	PAGE 17.3 	Table of interpreter instructions

≥	043236	170000				CFCC
≠BGT≡≥	043240	003007				BGT	1$		;Else go and compute the axis of rotation
≠CLRF≡≡AC0≡≥	043242	170400				CLRF	AC0
≠STF≡≡AC0≡≡AC3≡≥	043244	174003				STF	AC0,AC3
≠STF≡≡AC0≡≡AC4≡≥	043246	174004				STF	AC0,AC4		;NILROT = 0 degrees about (0,0,1)
≠LDF≡≡ONE≡≡AC1≡≥	043250	172567	006056			LDF	ONE,AC1
≠STF≡≡AC1≡≡AC5≡≥	043254	174105				STF	AC1,AC5
≠RTS≡≡PC≡≥	043256	000207				RTS	PC
≠STF≡≡AC0≡≡SP≡≥	043260	174046			1$:	STF	AC0,-(SP)	;Store COS(angle) away for later
≠NEGF≡≡AC3≡≥	043262	170703				NEGF	AC3
≠ADDF≡≡TWO≡≡AC3≡≥	043264	172367	777414			ADDF	TWO,AC3		;AC3 ← 3 - (1,1) - (2,2) - (3,3)
≠LDF≡≡ONE≡≡AC0≡≥	043270	172467	006036			LDF	ONE,AC0
≠SUBF≡≡R2≡≡AC0≡≥	043274	173012				SUBF	(R2),AC0	;(1,1)
≠SUBF≡≡R2≡≡AC0≡≥	043276	173062	000020			SUBF	20(R2),AC0	;(2,2)
≠ADDF≡≡R2≡≡AC0≡≥	043302	172062	000040			ADDF	40(R2),AC0	;(3,3)
≠DIVF≡≡AC3≡≡AC0≡≥	043306	174403				DIVF	AC3,AC0		;AC0 ← Z↑2
≠CMPF≡≡C0001≡≡AC0≡≥	043310	173467	777404			CMPF	C0001,AC0
≠CFCC≡≠CFCC≡≥	043314	170000				CFCC
≠BLT≡≥	043316	002426				BLT	3$		;If Z > 0.0001 skip ahead
≠CLRF≡≡AC5≡≥	043320	170405				CLRF	AC5		;Set Z ← 0
≠LDF≡≡ONE≡≡AC0≡≥	043322	172467	006004			LDF	ONE,AC0
≠SUBF≡≡R2≡≡AC0≡≥	043326	173012				SUBF	(R2),AC0	;(1,1)
≠ADDF≡≡R2≡≡AC0≡≥	043330	172062	000020			ADDF	20(R2),AC0	;(2,2)
≠SUBF≡≡R2≡≡AC0≡≥	043334	173062	000040			SUBF	40(R2),AC0	;(3,3)
≠DIVF≡≡AC3≡≡AC0≡≥	043340	174403				DIVF	AC3,AC0		;AC0 ← Y↑2
≠CMPF≡≡C0001≡≡AC0≡≥	043342	173467	777352			CMPF	C0001,AC0
≠CFCC≡≠CFCC≡≥	043346	170000				CFCC
≠BLT≡≥	043350	002404				BLT	2$		;If Y > 0.0001 skip ahead
≠CLRF≡≡AC4≡≥	043352	170404				CLRF	AC4		;Set Y ← 0
≠LDF≡≡ONE≡≡AC3≡≥	043354	172767	005752			LDF	ONE,AC3		;Set X ← 1
≠BR≡≥	043360	000447				BR	5$		;Skip to end
≠JSR≡≡PC≡≡LSQRTF≡≥	043362	004777	750450		2$:	JSR	PC,@LSQRTF	;Get SQRT(Y↑2)
≠STF≡≡AC0≡≡AC4≡≥	043366	174004				STF	AC0,AC4
≠LDF≡≡AC5≡≡AC2≡≥	043370	172605				LDF	AC5,AC2		;Clear this for later
≠BR≡≥	043372	000432				BR	4$		;Skip ahead to where X is computed
≠JSR≡≡PC≡≡LSQRTF≡≥	043374	004777	750436		3$:	JSR	PC,@LSQRTF	;Get SQRT(Z↑2)
≠STF≡≡AC0≡≡AC5≡≥	043400	174005				STF	AC0,AC5
≠LDF≡≡ONE≡≡AC2≡≥	043402	172667	005724			LDF	ONE,AC2
≠STF≡≡AC2≡≡AC3≡≥	043406	174203				STF	AC2,AC3		;For later
≠SUBF≡≡R2≡≡AC2≡≥	043410	173212				SUBF	(R2),AC2	;(1,1)
≠LDF≡≡R2≡≡AC0≡≥	043412	172462	000014			LDF	14(R2),AC0	;(1,2)
≠DIVF≡≡AC2≡≡AC0≡≥	043416	174402				DIVF	AC2,AC0		;AC0 ← (1,2) / [ 1 - (1,1) ]
≠LDF≡≡R2≡≡AC2≡≥	043420	172662	000010			LDF	10(R2),AC2	;(3,1)
≠MULF≡≡AC0≡≡AC2≡≥	043424	171200				MULF	AC0,AC2
≠ADDF≡≡R2≡≡AC2≡≥	043426	172262	000020			ADDF	20(R2),AC2	;(3,2)
≠MULF≡≡R2≡≡AC0≡≥	043432	171062	000004			MULF	4(R2),AC0	;(2,1)
≠SUBF≡≡AC0≡≡AC3≡≥	043436	173300				SUBF	AC0,AC3
≠SUBF≡≡R2≡≡AC3≡≥	043440	173362	000020			SUBF	20(R2),AC3	;(2,2)
≠DIVF≡≡AC3≡≡AC2≡≥	043444	174603				DIVF	AC3,AC2		;AC2 ← [(3,2)+(3,1)*(1,2)/[1-(1,1)] /
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 150
	INTERP PAL[HAL,HE]	PAGE 17.4 	Table of interpreter instructions

≥									;	[1-(2,2)-(2,1)*(1,2)/[1-(1,1)]
≠MULF≡≡AC5≡≡AC2≡≥	043446	171205				MULF	AC5,AC2
≠STF≡≡AC2≡≡AC4≡≥	043450	174204				STF	AC2,AC4		;AC4 ← Y
≠LDF≡≡R2≡≡AC2≡≥	043452	172662	000010			LDF	10(R2),AC2	;(3,1)
≠MULF≡≡AC5≡≡AC2≡≥	043456	171205				MULF	AC5,AC2		;Z
≠LDF≡≡R2≡≡AC3≡≥	043460	172762	000004		4$:	LDF	4(R2),AC3	;(2,1)
≠MULF≡≡AC4≡≡AC3≡≥	043464	171304				MULF	AC4,AC3		;Y
≠ADDF≡≡AC2≡≡AC3≡≥	043466	172302				ADDF	AC2,AC3
≠LDF≡≡ONE≡≡AC1≡≥	043470	172567	005636			LDF	ONE,AC1
≠SUBF≡≡R2≡≡AC1≡≥	043474	173112				SUBF	(R2),AC1	;(1,1)
≠DIVF≡≡AC1≡≡AC3≡≥	043476	174701				DIVF	AC1,AC3		;AC3 ← [(2,1)*Y+(3,1)*Z] / [1-(1,1)] = X
≠LDF≡≡SP≡≡AC0≡≥	043500	172426			5$:	LDF	(SP)+,AC0	;Retrieve the COS(angle)
≠RTS≡≡PC≡≥	043502	000207				RTS	PC		; & Return to TAXIS or TMAGN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 151
	INTERP PAL[HAL,HE]	PAGE 18 	Table of interpreter instructions

≥					;Return vectors: SVMUL, TVMUL, VMAKE, VADD, VSUB
≥					
≥					;83 -- 91 microseconds
≥					SVMUL:	;Vector ← Scalar * Vector.  Interpreter routine
≥						;X ← S*X,  Y ← S*Y,  Z ← S*Z,  W ← W
≠JSR≡≡PC≡≡NOCMP≡≥	043504	004767	767646			JSR PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETVEC≡≥	043510	004767	772732			JSR PC,GETVEC	;R0 ← -(R3) ← LOC[new vector block]
≠MOV≡≡R3≡≡R2≡≥	043514	016302	000002			MOV 2(R3),R2	;R2 ← LOC[arg2]  (the vector)
≠LDF≡≡R3≡≡AC0≡≥	043520	172473	000004			LDF @4(R3),AC0	;AC0 ← arg1 (the scalar)
≠MOV≡≡R1≡≥	043524	012701	000003			MOV #3,R1	;R1 ← 3:  How many fields to handle
≠LDF≡≡R2≡≡AC1≡≥	043530	172522			1$:	LDF (R2)+,AC1	;AC1 ← next field of vector
≠MULF≡≡AC0≡≡AC1≡≥	043532	171100				MULF AC0,AC1	;AC1 ← product
≠STF≡≡AC1≡≡R0≡≥	043534	174120				STF AC1,(R0)+	;Store result
≠SOB≡≡R1≡≥	043536	077104				SOB R1,1$	;Loop until all 3 fields done.
≠MOV≡≡R2≡≡R0≡≥	043540	012220				MOV (R2)+,(R0)+	;Transfer W
≠MOV≡≡R2≡≡R0≡≥	043542	012220				MOV (R2)+,(R0)+	;  which is 2 words long.
≠MOV≡≡R3≡≡R3≡≥	043544	012363	000002			MOV (R3)+,2(R3)	;Fix-up stack
≠TST≡≡R3≡≥	043550	005723				TST (R3)+
≠JSR≡≡PC≡≡YESCMP≡≥	043552	004767	767622			JSR PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	043556	000207				RTS PC		;Done
≥					
≥					VMAKE:	;Interpreter routine
≠LDF≡≡R3≡≡AC3≡≥	043560	172733				LDF @(R3)+,AC3	;Fetch arg3 (Z)
≠LDF≡≡R3≡≡AC2≡≥	043562	172633				LDF @(R3)+,AC2	;Fetch arg2 (Y)
≠LDF≡≡R3≡≡AC1≡≥	043564	172533				LDF @(R3)+,AC1	;Fetch arg1 (X)
≠JSR≡≡PC≡≡NOCMP≡≥	043566	004767	767564			JSR PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETVEC≡≥	043572	004767	772650			JSR PC,GETVEC	;R0 ← -(R3) ← LOC[new vector]
≠STF≡≡AC1≡≡R0≡≥	043576	174120				STF AC1,(R0)+	;Store X
≠STF≡≡AC2≡≡R0≡≥	043600	174220				STF AC2,(R0)+	;Store Y
≠STF≡≡AC3≡≡R0≡≥	043602	174320				STF AC3,(R0)+	;Store Z
≠MOV≡≡ONE≡≡R0≡≥	043604	016720	005522			MOV ONE,(R0)+	;Store W
≠CLR≡≡R0≡≥	043610	005010				CLR (R0)	;Store W (second word)
≠JSR≡≡PC≡≡YESCMP≡≥	043612	004767	767562			JSR PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	043616	000207				RTS PC		;Done
≥					
≥					VADD:	;Interpreter routine
≠JSR≡≡PC≡≡NOCMP≡≥	043620	004767	767532			JSR PC,NOCMP	;Don't compact for a bit
≠MOV≡≡R3≡≡R0≡≥	043624	012300				MOV (R3)+,R0	;R0 ← LOC[arg 2] (a vector)
≠MOV≡≡R3≡≡R1≡≥	043626	012301				MOV (R3)+,R1	;R1 ← LOC[arg 1] (a vector)
≠LDF≡≡R0≡≡AC1≡≥	043630	172520				LDF (R0)+,AC1	;Calculate X
≠ADDF≡≡R1≡≡AC1≡≥	043632	172121				ADDF (R1)+,AC1	;
≠LDF≡≡R0≡≡AC2≡≥	043634	172620				LDF (R0)+,AC2	;Calculate Y
≠ADDF≡≡R1≡≡AC2≡≥	043636	172221				ADDF (R1)+,AC2	;
≠LDF≡≡R0≡≡AC3≡≥	043640	172720				LDF (R0)+,AC3	;Calculate Z
≠ADDF≡≡R1≡≡AC3≡≥	043642	172321				ADDF (R1)+,AC3	;
≠JSR≡≡PC≡≡GETVEC≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 152
	INTERP PAL[HAL,HE]	PAGE 18.1 	Table of interpreter instructions

≥	043644	004767	772576		VRET:	JSR PC,GETVEC	;R0 ← -(R3) ← LOC[new vector]
≠STF≡≡AC1≡≡R0≡≥	043650	174120				STF AC1,(R0)+	;Store X
≠STF≡≡AC2≡≡R0≡≥	043652	174220				STF AC2,(R0)+	;Store Y
≠STF≡≡AC3≡≡R0≡≥	043654	174320				STF AC3,(R0)+	;Store Z
≠MOV≡≡ONE≡≡R0≡≥	043656	016720	005450			MOV ONE,(R0)+	;Assume W is 1
≠CLR≡≡R0≡≥	043662	005010				CLR (R0)	;
≠JSR≡≡PC≡≡YESCMP≡≥	043664	004767	767510			JSR PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	043670	000207				RTS PC		;Done
≥					
≥					VSUB:	;Interpreter routine
≠JSR≡≡PC≡≡NOCMP≡≥	043672	004767	767460			JSR PC,NOCMP	;Don't compact for a bit
≠MOV≡≡R3≡≡R1≡≥	043676	012301				MOV (R3)+,R1	;R1 ← LOC[arg 2] (a vector)
≠MOV≡≡R3≡≡R0≡≥	043700	012300				MOV (R3)+,R0	;R0 ← LOC[arg 1] (a vector)
≠LDF≡≡R0≡≡AC1≡≥	043702	172520				LDF (R0)+,AC1	;Calculate X
≠SUBF≡≡R1≡≡AC1≡≥	043704	173121				SUBF (R1)+,AC1	;
≠LDF≡≡R0≡≡AC2≡≥	043706	172620				LDF (R0)+,AC2	;Calculate Y
≠SUBF≡≡R1≡≡AC2≡≥	043710	173221				SUBF (R1)+,AC2	;
≠LDF≡≡R0≡≡AC3≡≥	043712	172720				LDF (R0)+,AC3	;Calculate Z
≠SUBF≡≡R1≡≡AC3≡≥	043714	173321				SUBF (R1)+,AC3	;
≠BR≡≡VRET≡≥	043716	000752				BR VRET		;Use common end code in VADD above
≥					
≥					;283 -- 324 microseconds
≥					TVMUL:	;Vector ← Trans * Vector.  Interpreter routine
≠JSR≡≡PC≡≡NOCMP≡≥	043720	004767	767432			JSR PC,NOCMP	;Don't compact for a bit
≠MOV≡≡R3≡≡R2≡≥	043724	011302				MOV (R3),R2	;R2 ← LOC[arg2] (the vector)
≠MOV≡≡R3≡≡R0≡≥	043726	016300	000002			MOV 2(R3),R0	;R0 ← LOC[arg1] (the trans)
≠CLRF≡≡AC1≡≥	043732	170401				CLRF AC1	;X ← 0
≠CLRF≡≡AC2≡≥	043734	170402				CLRF AC2	;Y ← 0
≠CLRF≡≡AC3≡≥	043736	170403				CLRF AC3	;Z ← 0
≠MOV≡≡R1≡≥	043740	012701	000004			MOV #4,R1	;R1 ← How many columns left to go
≠LDF≡≡R2≡≡AC0≡≥	043744	172422			1$:	LDF (R2)+,AC0	;AC0 ← field of vector
≠STF≡≡AC0≡≡AC5≡≥	043746	174005				STF AC0,AC5	;AC5 ← copy of AC0
≠MULF≡≡R0≡≡AC0≡≥	043750	171020				MULF (R0)+,AC0	;
≠ADDF≡≡AC0≡≡AC1≡≥	043752	172100				ADDF AC0,AC1	;Add partial result to X
≠LDF≡≡AC5≡≡AC0≡≥	043754	172405				LDF AC5,AC0	;Restore AC0
≠MULF≡≡R0≡≡AC0≡≥	043756	171020				MULF (R0)+,AC0	;
≠ADDF≡≡AC0≡≡AC2≡≥	043760	172200				ADDF AC0,AC2	;Add partial result to Y
≠LDF≡≡AC5≡≡AC0≡≥	043762	172405				LDF AC5,AC0	;Restore AC0
≠MULF≡≡R0≡≡AC0≡≥	043764	171020				MULF (R0)+,AC0	;
≠ADDF≡≡AC0≡≡AC3≡≥	043766	172300				ADDF AC0,AC3	;Add partial result to Z.
≠SOB≡≡R1≡≥	043770	077113				SOB R1,1$	;Go back to do all 4 columns.
≠JSR≡≡PC≡≡GETVEC≡≥	043772	004767	772450			JSR PC,GETVEC	;R0 ← -(R3) ← LOC[new vector]
≠STF≡≡AC1≡≡R0≡≥	043776	174120				STF AC1,(R0)+	;Store X
≠STF≡≡AC2≡≡R0≡≥	044000	174220				STF AC2,(R0)+	;Store Y
≠STF≡≡AC3≡≡R0≡≥	044002	174320				STF AC3,(R0)+	;Store Z
≠MOV≡≡R2≡≡R0≡≥	044004	016220	777774			MOV -4(R2),(R0)+;Copy W from the vector
≠MOV≡≡R2≡≡R0≡≥	044010	016210	777776			MOV -2(R2),(R0)	;  (2 words long)
≠MOV≡≡R3≡≡R3≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 153
	INTERP PAL[HAL,HE]	PAGE 18.2 	Table of interpreter instructions

≥	044014	012363	000002			MOV (R3)+,2(R3)	;Put result cell where first arg was
≠TST≡≡R3≡≥	044020	005723				TST (R3)+	; & fix up stack
≠JSR≡≡PC≡≡YESCMP≡≥	044022	004767	767352			JSR PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	044026	000207				RTS PC		;Done
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 154
	INTERP PAL[HAL,HE]	PAGE 19 	Table of interpreter instructions

≥					;Return a trans: TMAKE, TVADD, TVSUB, TTMUL, TINVRT, VSAXWR
≥					
≥					TMAKE:	;Interpreter routine.
≥					;All that is required is to take the rot part of the first argument,
≥					;and the vector from the second part;
≠JSR≡≡PC≡≡NOCMP≡≥	044030	004767	767322			JSR PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETTRN≡≥	044034	004767	772430			JSR PC,GETTRN	;R0 ← -(R3) ← LOC[new trans]
≠MOV≡≡R3≡≡R2≡≥	044040	016302	000004			MOV 4(R3),R2	;R2 ← LOC[arg 1] (the trans)
≠MOV≡≡R1≡≥	044044	012701	000011			MOV #11,R1	;R1 ← Count of how many copies to make
≠MOV≡≡R2≡≡R0≡≥	044050	012220			1$:	MOV (R2)+,(R0)+	;Transfer first half of floating word
≠MOV≡≡R2≡≡R0≡≥	044052	012220				MOV (R2)+,(R0)+	;Transfer second half of floating word
≠SOB≡≡R1≡≥	044054	077103				SOB R1,1$	;Repeat until done
≠MOV≡≡R3≡≡R2≡≥	044056	016302	000002			MOV 2(R3),R2	;R2 ← LOC[arg 2] (the vector)
≠MOV≡≡R1≡≥	044062	012701	000003			MOV #3,R1	;R1 ← Count of how many copies to make
≠MOV≡≡R2≡≡R0≡≥	044066	012220			2$:	MOV (R2)+,(R0)+	;Transfer first half of floating word
≠MOV≡≡R2≡≡R0≡≥	044070	012220				MOV (R2)+,(R0)+ ;Transfer second half of floating word
≠SOB≡≡R1≡≥	044072	077103				SOB R1,2$	;Repeat until done
≠MOV≡≡R3≡≡R3≡≥	044074	012363	000002			MOV (R3)+,2(R3)	;Fix-up stack
≠TST≡≡R3≡≥	044100	005723				TST (R3)+
≠JSR≡≡PC≡≡YESCMP≡≥	044102	004767	767272			JSR PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	044106	000207				RTS PC		;Done.
≥					
≥					TVCOM:	;Utility routine used to do common code in TVADD & TVSUB
≠JSR≡≡PC≡≡NOCMP≡≥	044110	004767	767242			JSR PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETTRN≡≥	044114	004767	772350			JSR PC,GETTRN	;R0 ← -(R3) ← LOC[new trans]
≠MOV≡≡R3≡≡R2≡≥	044120	016302	000002			MOV 2(R3),R2	;R2 ← LOC[arg 2] (the vector)
≠MOV≡≡R3≡≡R1≡≥	044124	016301	000004			MOV 4(R3),R1	;R1 ← LOC[arg 1] (the trans)
≠MOV≡≡R3≡≥	044130	012703	000011			MOV #11,R3	;R3 ← Count of how many copies to make
≠MOV≡≡R1≡≡R0≡≥	044134	012120			1$:	MOV (R1)+,(R0)+	;Transfer first half of floating word
≠MOV≡≡R1≡≡R0≡≥	044136	012120				MOV (R1)+,(R0)+	;Transfer second half of floating word
≠SOB≡≡R3≡≥	044140	077303				SOB R3,1$	;Repeat until done
≠MOV≡≡R3≡≥	044142	012703	000003			MOV #3,R3	;R3 ← Count of how many additions to perform
≠RTS≡≡PC≡≥	044146	000207				RTS PC		;Return to TVADD or TVSUB
≥					
≥					TVADD:	;Interpreter routine.
≥					;All that is required is to take the rot part of the first argument,
≥					;and add the vector from the first part to the second argument.
≠MOV≡≡R3≡≡SP≡≥	044150	010346				MOV R3,-(SP)	;Save R3
≠JSR≡≡PC≡≡TVCOM≡≥	044152	004767	777732			JSR PC,TVCOM	;Do the common code for TVADD & TVSUB
≠LDF≡≡R1≡≡AC0≡≥	044156	172421			1$:	LDF (R1)+,AC0	;AC0 ← word from trans
≠ADDF≡≡R2≡≡AC0≡≥	044160	172022				ADDF (R2)+,AC0	;  + word from vector
≠STF≡≡AC0≡≡R0≡≥	044162	174020				STF AC0,(R0)+	;
≠SOB≡≡R3≡≥	044164	077304				SOB R3,1$	;Repeat until done
≠MOV≡≡SP≡≡R3≡≥	044166	012603			TVRET:	MOV (SP)+,R3	;Restore R3
≠MOV≡≡R3≡≡R3≡≥	044170	016363	777776	000002		MOV -2(R3),2(R3)	;Fix-up stack (pretty strange huh?)
≠TST≡≡R3≡≥	044176	005723				TST (R3)+
≠JSR≡≡PC≡≡YESCMP≡≥	044200	004767	767174			JSR PC,YESCMP	;OK to compact now
≤CCC≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 155
	INTERP PAL[HAL,HE]	PAGE 19.1 	Table of interpreter instructions

≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	044204	000207				RTS PC		;Done.
≥					
≥					TVSUB:	;Interpreter routine.
≥					;All that is required is to take the rot part of the first argument,
≥					;and subtract the second argument from the vector of the first arg.
≠MOV≡≡R3≡≡SP≡≥	044206	010346				MOV R3,-(SP)	;Save R3
≠JSR≡≡PC≡≡TVCOM≡≥	044210	004767	777674			JSR PC,TVCOM	;Do the common code for TVADD & TVSUB
≠LDF≡≡R1≡≡AC0≡≥	044214	172421			1$:	LDF (R1)+,AC0	;AC0 ← word from trans
≠SUBF≡≡R2≡≡AC0≡≥	044216	173022				SUBF (R2)+,AC0	;  + word from vector
≠STF≡≡AC0≡≡R0≡≥	044220	174020				STF AC0,(R0)+	;
≠SOB≡≡R3≡≥	044222	077304				SOB R3,1$	;Repeat until done
≠BR≡≡TVRET≡≥	044224	000760				BR  TVRET	;Do common end code & return
≥					
≥					TTMUL:	;Interpreter routine
≥					;Multiplies two transes together.
≠MOV≡≡R4≡≡SP≡≥	044226	010446				MOV R4,-(SP)	;Save R4
≠JSR≡≡PC≡≡NOCMP≡≥	044230	004767	767122			JSR PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETTRN≡≥	044234	004767	772230			JSR PC,GETTRN	;R0 ← -(R3) ← LOC[new trans]
≠MOV≡≡R3≡≡R2≡≥	044240	016302	000002			MOV 2(R3),R2	;R2 ← LOC[arg 2]
≠MOV≡≡R3≡≡R4≡≥	044244	016304	000004			MOV 4(R3),R4	;R4 ← LOC[arg 1]
≠MOV≡≡R3≡≡SP≡≥	044250	010346				MOV R3,-(SP)	;Save R3
≠MOV≡≡R4≡≡SP≡≥	044252	010446				MOV R4,-(SP)	;Save a copy of R4
≠MOV≡≡R1≡≥	044254	012701	000004			MOV #4,R1	;Loop count for cols of answer
≠LDF≡≡R2≡≡AC1≡≥	044260	172522			1$:	LDF (R2)+,AC1	;Pick up a column of arg2: First row
≠LDF≡≡R2≡≡AC2≡≥	044262	172622				LDF (R2)+,AC2	;  Second row
≠LDF≡≡R2≡≡AC3≡≥	044264	172722				LDF (R2)+,AC3	;  Third row
≠STF≡≡AC3≡≡AC4≡≥	044266	174304				STF AC3,AC4	;    store in AC4
≠MOV≡≡R3≡≥	044270	012703	000003			MOV #3,R3	;Loop count for rows of answer
≠LDF≡≡R4≡≡AC3≡≥	044274	172714			2$:	LDF (R4),AC3	;First col of arg 1
≠MULF≡≡AC1≡≡AC3≡≥	044276	171301				MULF AC1,AC3	;
≠LDF≡≡R4≡≡AC0≡≥	044300	172464	000014			LDF 14(R4),AC0	;Second col of arg 1
≠MULF≡≡AC2≡≡AC0≡≥	044304	171002				MULF AC2,AC0	;
≠ADDF≡≡AC0≡≡AC3≡≥	044306	172300				ADDF AC0,AC3	;
≠LDF≡≡R4≡≡AC0≡≥	044310	172464	000030			LDF 30(R4),AC0	;Third col of arg 1
≠MULF≡≡AC4≡≡AC0≡≥	044314	171004				MULF AC4,AC0	;
≠ADDF≡≡AC0≡≡AC3≡≥	044316	172300				ADDF AC0,AC3	;
≠STF≡≡AC3≡≡R0≡≥	044320	174320				STF AC3,(R0)+	;
≠ADD≡≡R4≡≥	044322	062704	000004			ADD #4,R4	;Move to the next column of arg 1
≠SOB≡≡R3≡≥	044326	077316				SOB R3,2$	;Repeat for first 3 rows of answer
≠MOV≡≡SP≡≡R4≡≥	044330	011604				MOV (SP),R4	;Reset R4 to point to first row of arg 1
≠SOB≡≡R1≡≥	044332	077126				SOB R1,1$	;Repeat for all four columns of answer
≠LDF≡≡R0≡≡AC1≡≥	044334	172560	777764			LDF -14(R0),AC1	;Add correction for last column, first row
≠ADDF≡≡R4≡≡AC1≡≥	044340	172164	000044			ADDF 44(R4),AC1	;
≠STF≡≡AC1≡≡R0≡≥	044344	174160	777764			STF AC1,-14(R0)	;
≠LDF≡≡R0≡≡AC1≡≥	044350	172560	777770			LDF -10(R0),AC1	;Add correction for last column, second row
≠ADDF≡≡R4≡≡AC1≡≥	044354	172164	000050			ADDF 50(R4),AC1	;
≠STF≡≡AC1≡≡R0≡≥	044360	174160	777770			STF AC1,-10(R0)	;
≠LDF≡≡R0≡≡AC1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 156
	INTERP PAL[HAL,HE]	PAGE 19.2 	Table of interpreter instructions

≥	044364	172560	777774			LDF -4(R0),AC1	;Add correction for last column, third row
≠ADDF≡≡R4≡≡AC1≡≥	044370	172164	000054			ADDF 54(R4),AC1	;
≠STF≡≡AC1≡≡R0≡≥	044374	174160	777774			STF AC1,-4(R0)	;
≠TST≡≡SP≡≥	044400	005726				TST (SP)+	;Pop the R4 temp
≠MOV≡≡SP≡≡R3≡≥	044402	012603				MOV (SP)+,R3	;Restore R3
≠MOV≡≡SP≡≡R4≡≥	044404	012604				MOV (SP)+,R4	;Restore R4
≠MOV≡≡R3≡≡R3≡≥	044406	012363	000002			MOV (R3)+,2(R3)	;Fix-up stack
≠TST≡≡R3≡≥	044412	005723				TST (R3)+
≠JSR≡≡PC≡≡YESCMP≡≥	044414	004767	766760			JSR PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	044420	000207				RTS PC		;Done
≥					
≥					TINVRT:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Inverts a trans.
≥					  The result, (rot',trslat'), is defined:
≥									rot' = transpose(rot)
≥									trslat' = -(rot'*trslat)
≥					⊗
≠JSR≡≡PC≡≡NOCMP≡≥	044422	004767	766730			JSR PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡GETTRN≡≥	044426	004767	772036			JSR PC,GETTRN	;R0 ← -(R3) ← LOC[new trans] + 4*interation number
≠MOV≡≡R3≡≡R2≡≥	044432	016302	000002			MOV 2(R3),R2	;R2 ← LOC[old trans], travels down the whole trans
≠MOV≡≡R3≡≡SP≡≥	044436	010346				MOV R3,-(SP)	;Save R3
≠MOV≡≡R4≡≡SP≡≥	044440	010446				MOV R4,-(SP)	;Save R4
≠MOV≡≡R0≡≡R3≡≥	044442	010003				MOV R0,R3	;R3 ← LOC[new trans] + 20*interation number
≠MOV≡≡R2≡≡R4≡≥	044444	010204				MOV R2,R4	;R4 ← LOC[old trans], stays constant
≠MOV≡≡R1≡≥	044446	012701	000003			MOV #3,R1	;Three columns to do
≥					1$:	;Transpose a column, multiplying by the translation
≠CLRF≡≡AC1≡≥	044452	170401				CLRF AC1	;Cumulative product
≠LDF≡≡R2≡≡AC0≡≥	044454	172422				LDF (R2)+,AC0	;Take from the source rotation
≠STF≡≡AC0≡≡R0≡≥	044456	174010				STF AC0,(R0)	;  into the transpose,
≠MULF≡≡R4≡≡AC0≡≥	044460	171064	000044			MULF 44(R4),AC0	;
≠SUBF≡≡AC0≡≡AC1≡≥	044464	173100				SUBF AC0,AC1	;accumulate the product.
≠LDF≡≡R2≡≡AC0≡≥	044466	172422				LDF (R2)+,AC0	;Take from the source rotation
≠STF≡≡AC0≡≡R0≡≥	044470	174060	000014			STF AC0,14(R0)	;  into the transpose,
≠MULF≡≡R4≡≡AC0≡≥	044474	171064	000050			MULF 50(R4),AC0	;
≠SUBF≡≡AC0≡≡AC1≡≥	044500	173100				SUBF AC0,AC1	;accumulate the product.
≠LDF≡≡R2≡≡AC0≡≥	044502	172422				LDF (R2)+,AC0	;Take from the source rotation
≠STF≡≡AC0≡≡R0≡≥	044504	174060	000030			STF AC0,30(R0)	;  into the transpose
≠MULF≡≡R4≡≡AC0≡≥	044510	171064	000054			MULF 54(R4),AC0	;
≠SUBF≡≡AC0≡≡AC1≡≥	044514	173100				SUBF AC0,AC1	;accumulate the product
≠STF≡≡AC1≡≡R0≡≥	044516	174160	000044			STF AC1,44(R0)	;Place the new translation
≠ADD≡≡R0≡≥	044522	062700	000004			ADD #4,R0	;Move to next row of result
≠ADD≡≡R3≡≥	044526	062703	000014			ADD #14,R3	;Move to next column of result
≠SOB≡≡R1≡≥	044532	077131				SOB R1,1$	;
≠MOV≡≡SP≡≡R4≡≥	044534	012604				MOV (SP)+,R4	;Restore R4
≠MOV≡≡SP≡≡R3≡≥	044536	012603				MOV (SP)+,R3	;Restore R3
≠MOV≡≡R3≡≡R3≡≥	044540	012313				MOV (R3)+,(R3)	;Fix-up stack
≠JSR≡≡PC≡≡YESCMP≡≥	044542	004767	766632			JSR PC,YESCMP	;OK to compact now
≤CCC≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 157
	INTERP PAL[HAL,HE]	PAGE 19.3 	Table of interpreter instructions

≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	044546	000207				RTS PC		;Done
≥					
≥					VSAXWR:	;Interpreter Routine	coded by ARG 5/3/76
≥					;Produces a trans that rotates about a vector by a given angle
≠MOV≡≡R5≡≡SP≡≥	044550	010546				MOV R5,-(SP)		;Save R5
≠LDF≡≡R3≡≡AC2≡≥	044552	172633				LDF @(R3)+,AC2		;Save angle in AC2
≠JSR≡≡PC≡≡UNITV≡≥	044554	004767	775716			JSR PC,UNITV		;Convert vector to unit vector
≠STF≡≡AC2≡≡AC0≡≥	044560	174200				STF AC2,AC0		;Retrieve angle
≠JSR≡≡PC≡≡LSNCSD≡≥	044562	004777	747252			JSR PC,@LSNCSD		;Get sin & cos of angle
≠STF≡≡AC0≡≡AC4≡≥	044566	174004				STF AC0,AC4		;Save sin in AC4
≠STF≡≡AC1≡≡AC5≡≥	044570	174105				STF AC1,AC5		;Save cos in AC5
≠SUBF≡≡ONE≡≡AC1≡≥	044572	173167	004534			SUBF ONE,AC1		;AC1←(1-COS)
≠NEGF≡≡AC1≡≥	044576	170701				NEGF AC1
≠JSR≡≡PC≡≡NOCMP≡≥	044600	004767	766552			JSR PC,NOCMP		;Don't compact for a bit
≠JSR≡≡PC≡≡GETTRN≡≥	044604	004767	771660			JSR PC,GETTRN		;R0←-(R3)←LOC[New Tran]
≠MOV≡≡R3≡≡R1≡≥	044610	016301	000002			MOV 2(R3),R1		;R1←LOC[Unit Vec]
≠MOV≡≡SP≡≥	044614	012746	000003			MOV #3,-(SP)		;Three columns to do
≠MOV≡≡R5≡≥	044620	012705	000003		1$:	MOV #3,R5		;Three rows to do
≠MOV≡≡R3≡≡R2≡≥	044624	016302	000002			MOV 2(R3),R2		;R2←LOC[Unit vec]
≠LDF≡≡AC1≡≡AC2≡≥	044630	172601				LDF AC1,AC2
≠MULF≡≡R1≡≡AC2≡≥	044632	171221				MULF (R1)+,AC2		;AC2←(1-COS)*U[i]
≠LDF≡≡AC2≡≡AC3≡≥	044634	172702			2$:	LDF AC2,AC3
≠MULF≡≡R2≡≡AC3≡≥	044636	171322				MULF (R2)+,AC3		;Trans[j,i]←(1-COS)*U[i]*U[j]
≠STF≡≡AC3≡≡R0≡≥	044640	174320				STF AC3,(R0)+
≠SOB≡≡R5≡≥	044642	077504				SOB R5,2$		;Do all 3 rows
≠DEC≡≡SP≡≥	044644	005316				DEC (SP)
≠BGT≡≥	044646	003364				BGT 1$			;Do all 3 columns
≠MOV≡≡SP≡≡R0≡≥	044650	012620				MOV (SP)+,(R0)+
≠CLR≡≡R0≡≥	044652	005020				CLR (R0)+		;Set up last column
≠CLR≡≡R0≡≥	044654	005020				CLR (R0)+
≠CLR≡≡R0≡≥	044656	005020				CLR (R0)+
≠CLR≡≡R0≡≥	044660	005020				CLR (R0)+
≠CLR≡≡R0≡≥	044662	005020				CLR (R0)+
≠MOV≡≡R5≡≥	044664	012705	000003			MOV #3,R5		;Three terms to do: (1,1) (2,2) & (3,3)
≠MOV≡≡R3≡≡R0≡≥	044670	011300				MOV (R3),R0		;R0←LOC[Trans]
≠LDF≡≡AC5≡≡AC1≡≥	044672	172505			3$:	LDF AC5,AC1		;AC1←COS
≠ADDF≡≡R0≡≡AC1≡≥	044674	172110				ADDF (R0),AC1		;Add COS to (1-COS)*U[i]*U[i] term
≠STF≡≡AC1≡≡R0≡≥	044676	174110				STF AC1,(R0)
≠ADD≡≡R0≡≥	044700	062700	000020			ADD #20,R0		;R0 points to next term to add COS to
≠SOB≡≡R5≡≥	044704	077506				SOB R5,3$		;Do all three terms
≠MOV≡≡R3≡≡R0≡≥	044706	011300				MOV (R3),R0		;R0←LOC[Trans]
≠MOV≡≡R3≡≡R1≡≥	044710	016301	000002			MOV 2(R3),R1		;R1←LOC[Unit Vec]
≠LDF≡≡R1≡≡AC2≡≥	044714	172621				LDF (R1)+,AC2		;AC2←U[X]
≠MULF≡≡AC4≡≡AC2≡≥	044716	171204				MULF AC4,AC2		;AC2←SIN*U[X]
≠STF≡≡AC2≡≡AC3≡≥	044720	174203				STF AC2,AC3		;Make a copy
≠ADDF≡≡R0≡≡AC2≡≥	044722	172260	000024			ADDF 24(R0),AC2		;Add it to the (3,2) term
≠STF≡≡AC2≡≡R0≡≥	044726	174260	000024			STF AC2,24(R0)
≠NEGF≡≡AC3≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 158
	INTERP PAL[HAL,HE]	PAGE 19.4 	Table of interpreter instructions

≥	044732	170703				NEGF AC3
≠ADDF≡≡R0≡≡AC3≡≥	044734	172360	000034			ADDF 34(R0),AC3		;Subtract it from the (2,3) term
≠STF≡≡AC3≡≡R0≡≥	044740	174360	000034			STF AC3,34(R0)
≠LDF≡≡R1≡≡AC2≡≥	044744	172621				LDF (R1)+,AC2		;AC2←U[Y]
≠MULF≡≡AC4≡≡AC2≡≥	044746	171204				MULF AC4,AC2		;AC2←SIN*U[Y]
≠STF≡≡AC2≡≡AC3≡≥	044750	174203				STF AC2,AC3		;Make a copy
≠ADDF≡≡R0≡≡AC2≡≥	044752	172260	000030			ADDF 30(R0),AC2		;Add it to the (1,3) term
≠STF≡≡AC2≡≡R0≡≥	044756	174260	000030			STF AC2,30(R0)
≠NEGF≡≡AC3≡≥	044762	170703				NEGF AC3
≠ADDF≡≡R0≡≡AC3≡≥	044764	172360	000010			ADDF 10(R0),AC3		;Subtract it from the (3,1) term
≠STF≡≡AC3≡≡R0≡≥	044770	174360	000010			STF AC3,10(R0)
≠LDF≡≡R1≡≡AC2≡≥	044774	172621				LDF (R1)+,AC2		;AC2←U[Z]
≠MULF≡≡AC4≡≡AC2≡≥	044776	171204				MULF AC4,AC2		;AC2←SIN*U[Z]
≠STF≡≡AC2≡≡AC3≡≥	045000	174203				STF AC2,AC3		;Make a copy
≠ADDF≡≡R0≡≡AC2≡≥	045002	172260	000004			ADDF 4(R0),AC2		;Add it to the (2,1) term
≠STF≡≡AC2≡≡R0≡≥	045006	174260	000004			STF AC2,4(R0)
≠NEGF≡≡AC3≡≥	045012	170703				NEGF AC3
≠ADDF≡≡R0≡≡AC3≡≥	045014	172360	000014			ADDF 14(R0),AC3		;Subtract it from the (1,2) term
≠STF≡≡AC3≡≡R0≡≥	045020	174360	000014			STF AC3,14(R0)		;Trans is done!
≠MOV≡≡SP≡≡R5≡≥	045024	012605				MOV (SP)+,R5		;Restore R5
≠MOV≡≡R3≡≡R3≡≥	045026	012313				MOV (R3)+,(R3)		;Clean up stack
≠JSR≡≡PC≡≡YESCMP≡≥	045030	004767	766344			JSR PC,YESCMP		;OK to compact now
≤CCC≡≥						CCC			;Clear condition codes
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	045034	000207				RTS PC			; & Return
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 159
	INTERP PAL[HAL,HE]	PAGE 20 	Table of interpreter instructions

≥					;Motion:  MOVE, CENTER, STOP, WHERE, NOTICE
≥					
≠.IFNZ≡≡MOVING≡≥		000001			.IFNZ MOVING	;If this version is supposed to be able to move
≥					
≥					MOVE:	;Interpreter routine
≠MOV≡≡LMOVE≡≡R2≡≥	045036	016702	746760			MOV LMOVE,R2	;Set for moving operation
≠JMP≡≡MOVSTA≡≥	045042	000167	000010			JMP MOVSTA	;Use the common move code
≥					
≥					CENTER:	;Interpreter routine
≠MOV≡≡LCENTE≡≡R2≡≥	045046	016702	746744			MOV LCENTER,R2	;Set for centering operation
≠JMP≡≡MOVSTA≡≥	045052	000167	000000			JMP MOVSTA	;Use the common move code
≥					
≡DVBKSZ≠≥		000012			DVBKSZ == 12		;Size of a device block
≥					
≠COMMEN≡≥				COMMENT ⊗ New version to update the frame afterwords.  Assumes that
≥				there are two arguments: a pointer to the trajectory table and a word
≥					of mechanism bits, to help in updating the necessary variables.  ⊗
≥					
≠MOV≡≡R0≡≥	045056	012700	000007		MOVSTA:	MOV #'π,R0	;Whistle while you work
≠JSR≡≡PC≡≡TYPCHR≡≥	045062	004767	747102			JSR PC,TYPCHR	;
≠MOV≡≡DVBKSZ≡≡R0≡≥	045066	012700	000012			MOV #DVBKSZ,R0	;Get a device block
≠JSR≡≡PC≡≡GTFREE≡≥	045072	004767	763150			JSR PC,GTFREE	;
≠MOV≡≡R0≡≡R1≡≥	045076	010001				MOV R0,R1	;R1 ← address of device block
≠MOV≡≡R0≡≡SP≡≥	045100	010046				MOV R0,-(SP)	;Save a copy on the stack
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	045102	017400	000000			MOV @IPC(R4),R0	;R0 ← address of coefficient list
≠JSR≡≡PC≡≡NOCMP≡≥	045106	004767	766244			JSR PC,NOCMP	;Don't compact for a bit
≠JSR≡≡PC≡≡R2≡≥	045112	004712				JSR PC,@R2	;Do some kind of move (MOVE, CENTER)
≠JSR≡≡PC≡≡YESCMP≡≥	045114	004767	766260			JSR PC,YESCMP	;OK to compact now
≠TST≡≡R0≡≥	045120	005700				TST R0		;Did the move succeed?
≠BEQ≡≥	045122	001415				BEQ 1$		;Yes
≠MOV≡≡R0≡≡SP≡≥	045124	010046				MOV R0,-(SP)	;  save error code
≠MOV≡≡MVMES1≡≡R0≡≥	045126	012700	045276			MOV #MVMES1,R0	;
≠JSR≡≡PC≡≡TYPSTR≡≥	045132	004767	746742			JSR PC,TYPSTR	;  Complain
≠MOV≡≡SP≡≡R0≡≥	045136	012600				MOV (SP)+,R0	;
≠JSR≡≡PC≡≡TYPOCT≡≥	045140	004767	746764			JSR PC,TYPOCT	;  Give error condition
≠MOV≡≡SP≡≡R1≡≥	045144	011601				MOV (SP),R1	;  put address of device block in R1
≤HALERR≡≥						HALERR MOVERR	;  and switch to DDT
≠MOV≡≡MOVERR≡≡SP≡≥	045146	012746	045320			MOV #MOVERR,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	045152	004777	746634			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤BMPIPC≡≥					1$:	BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	045156	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠MOV≡≡IPC≡≡R4≡≡R2≡≥	045164	017402	000000			MOV @IPC(R4),R2	;R2 ← mechanism bits
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	045170	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≥						;Invalidate the affected device variables;
≠.IFNZ≡≡YELLOW≡≥		000000			    .IFNZ YELLOW
≥						BIT #YARM,R2	;
≥						BEQ 2$		;
≥						MOV #YACOFS,R0	;
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 160
	INTERP PAL[HAL,HE]	PAGE 20.1 	Table of interpreter instructions

≥						JSR PC,GETARG	;
≥						MOV (R0),R0	;
≥						JSR PC,INVLDT	;
≥					2$:	BIT #YHAND,R2	;
≥						BEQ 3$		;
≥						MOV #YHCOFS,R0	;
≥						JSR PC,GETARG	;
≥						MOV (R0),R0	;
≥						JSR PC,INVLDT	;
≥					    .ENDC
≠BIT≡≡BARM≡≡R2≡≥	045176	032702	000004		3$:	BIT #BARM,R2	;
≠BEQ≡≥	045202	001407				BEQ 4$		;
≠MOV≡≡BACOFS≡≡R0≡≥	045204	012700	000010			MOV #BACOFS,R0	;
≠JSR≡≡PC≡≡GETARG≡≥	045210	004767	771046			JSR PC,GETARG	;
≠MOV≡≡R0≡≡R0≡≥	045214	011000				MOV (R0),R0	;
≠JSR≡≡PC≡≡INVLDT≡≥	045216	004767	013154			JSR PC,INVLDT	;
≠BIT≡≡BHAND≡≡R2≡≥	045222	032702	000010		4$:	BIT #BHAND,R2	;
≠BEQ≡≥	045226	001407				BEQ 5$		;
≠MOV≡≡BHCOFS≡≡R0≡≥	045230	012700	000012			MOV #BHCOFS,R0	;
≠JSR≡≡PC≡≡GETARG≡≥	045234	004767	771022			JSR PC,GETARG	;
≠MOV≡≡R0≡≡R0≡≥	045240	011000				MOV (R0),R0	;
≠JSR≡≡PC≡≡INVLDT≡≥	045242	004767	013130			JSR PC,INVLDT	;
≠MOV≡≡SP≡≡R0≡≥	045246	012600			5$:	MOV (SP)+,R0	;
≠JSR≡≡PC≡≡RLFREE≡≥	045250	004767	763334			JSR PC,RLFREE	;Get rid of the device block
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	045254	000207				RTS PC		;Return
≠TST≡≡SP≡≥	045256	005726			RETRY:	TST (SP)+	;Get here from HALERR; clean off stack
≠MOV≡≡SP≡≡R0≡≥	045260	012600				MOV (SP)+,R0	;
≠JSR≡≡PC≡≡RLFREE≡≥	045262	004767	763322			JSR PC,RLFREE	;Get rid of the device block
≤BACKIP≡≥						BACKIPC		;Backup IPC
≠SUB≡≡IPC≡≡R4≡≥	045266	162764	000002	000000		SUB #2,IPC(R4)	;Backup IPC
≠RTS≡≡PC≡≥	045274	000207				RTS PC		;
≥					
≤ASCIE≡≥				MVMES1:	ASCIE </
≥					SERVO ERROR = />
≠.ASCIZ≡≥	045276	   015		
≥	045277	   012			       .ASCIZ /
≥	045300	   123		
≥	045301	   105		
≥	045302	   122		
≥	045303	   126		
≥	045304	   117		
≥	045305	   040		
≥	045306	   105		
≥	045307	   122		
≥	045310	   122		
≥	045311	   117		
≥	045312	   122		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 161
	INTERP PAL[HAL,HE]	PAGE 20.2 	Table of interpreter instructions

≥	045313	   040		
≥	045314	   075		
≥	045315	   040		
≥	045316	   000		
≥					SERVO ERROR = /
≠.EVEN≡≥		045320			       .EVEN
≤ASCIE≡≥					MOVERR:	ASCIE </DEVICE BLOCK AT (R1). TO RETRY THE MOVE, RETRY$G/>
≠.ASCIZ≡≥	045320	   104		
≥	045321	   105		
≥	045322	   126		
≥	045323	   111		
≥	045324	   103		
≥	045325	   105		
≥	045326	   040		
≥	045327	   102		
≥	045330	   114		
≥	045331	   117		
≥	045332	   103		
≥	045333	   113		
≥	045334	   040		
≥	045335	   101		
≥	045336	   124		
≥	045337	   040		
≥	045340	   050		
≥	045341	   122		
≥	045342	   061		
≥	045343	   051		
≥	045344	   056		
≥	045345	   040		
≥	045346	   124		
≥	045347	   117		
≥	045350	   040		
≥	045351	   122		
≥	045352	   105		
≥	045353	   124		
≥	045354	   122		
≥	045355	   131		
≥	045356	   040		
≥	045357	   124		
≥	045360	   110		
≥	045361	   105		
≥	045362	   040		
≥	045363	   115		
≥	045364	   117		
≥	045365	   126		
≥	045366	   105		
≥	045367	   054		
≥	045370	   040		
≥	045371	   122		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 162
	INTERP PAL[HAL,HE]	PAGE 20.3 	Table of interpreter instructions

≥	045372	   105		
≥	045373	   124		
≥	045374	   122		
≥	045375	   131		
≥	045376	   044		
≥	045377	   107		
≥	045400	   000		
≥					       .ASCIZ /DEVICE BLOCK AT (R1). TO RETRY THE MOVE, RETRY$G/
≠.EVEN≡≥		045402			       .EVEN
≥					
≥					.IFF	;If not a moving version
≥					
≥					MOVE:
≥					CENTER:
≥						HALERR MOVERR	;Can't move
≥						BMPIPC		;Bump IPC
≥						BMPIPC		;Bump IPC
≥						CLR R0		;
≥						RTS PC		;Return
≥					
≥					MOVERR: ASCIE </SORRY, THIS VERSION CAN'T EVEN LIFT A FINGER/>
≥					
≥					.ENDC
≥					
≥					
≥					
≥					STOP:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Takes one argument, a set of mechanism bits.  (e.g. BARM,
≥				BHAND, YARM, YHAND).  For each one on, all the associated joints are
≥					stopped.  ⊗
≥					
≠MOV≡≡IPC≡≡R4≡≡R2≡≥	045402	017402	000000			MOV @IPC(R4),R2	;R2 ← mechanism bits
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	045406	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠MOV≡≡R2≡≡R0≡≥	045414	010200				MOV R2,R0	;R0 ← mech bits
≠JSR≡≡PC≡≡TABOFS≡≥	045416	004767	001170			JSR PC,TABOFS	;R0 ← table offset
≠BIT≡≡AHAND≡≡R2≡≥	045422	032702	000012			BIT #AHAND,R2	;A hand?
≠BNE≡≥	045426	001003				BNE 1$		;Yes
≠MOV≡≡R1≡≥	045430	012701	000006			MOV #6,R1	;R1 ← count of joints
≠BR≡≥	045434	000402				BR 2$
≠MOV≡≡R1≡≥	045436	012701	000001		1$:	MOV #1,R1	;R1 ← count of joints
≠ADD≡≡LDVCPT≡≡R0≡≥	045442	066700	746362		2$:	ADD LDVCPTR,R0	;R0 ← LOC[table of device pointers]
≠MOV≡≡R0≡≡R2≡≥	045446	012002			3$:	MOV (R0)+,R2	;R2 ← device block
≠BEQ≡≥	045450	001403				BEQ 4$		;If any
≠BIS≡≡R2≡≥	045452	052772	100000	000000		BIS #100000,@0(R2)	;Stop this device.
≠SOB≡≡R1≡≥	045460	077106			4$:	SOB R1,3$	;Repeat
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	045462	000207				RTS PC		;Done
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 163
	INTERP PAL[HAL,HE]	PAGE 20.4 	Table of interpreter instructions

≥					
≥					WHERE:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ One argument: The mechanism bits.  Puts value of that
≥					mechanism on the stack.  Only one mechanism at a time, please!  ⊗
≠MOV≡≡IPC≡≡R4≡≡R2≡≥	045464	017402	000000			MOV @IPC(R4),R2	;Mechanism bits
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	045470	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡NOCMP≡≥	045476	004767	765654			JSR PC,NOCMP	;Don't compact for a bit
≠BIT≡≡AHAND≡≡R2≡≥	045502	032702	000012			BIT #AHAND,R2	;A hand?
≠BNE≡≥	045506	001003				BNE 1$		;No.
≠JSR≡≡PC≡≡GETTRN≡≥	045510	004767	770754			JSR PC,GETTRN	;R0 ← -(R3) ← LOC[new trans]
≠BR≡≥	045514	000402				BR 2$
≠JSR≡≡PC≡≡GETSCA≡≥	045516	004767	770702		1$:	JSR PC,GETSCA	;R0 ← -(R3) ← LOC[new scalar]
≠MOV≡≡LTHPTR≡≡R1≡≥	045522	016701	746300		2$:	MOV LTHPTR,R1	;
≠JSR≡≡PC≡≡LUPDAT≡≥	045526	004777	746314			JSR PC,@LUPDATE	;
≠JSR≡≡PC≡≡YESCMP≡≥	045532	004767	765642			JSR PC,YESCMP	;OK to compact now
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	045536	000207				RTS PC		;Done
≥					
≥					NOTICE:
≠COMMEN≡≥				COMMENT ⊗ The arms may have been moved without our knowledge.  A call
≥				to this routine calls @LWHERE to find the real locations, and
≥				invalidates all manipulator variables.  This routine should be called
≥				from WAITE, but not from MOVE or CENTER.  It may be called from DDT,
≥					since it saves all registers.  ⊗
≠MOV≡≡R0≡≡SP≡≥	045540	010046				MOV R0,-(SP)	;Save R0
≠MOV≡≡R1≡≡SP≡≥	045542	010146				MOV R1,-(SP)	;Save R1
≠STF≡≡AC0≡≡SP≡≥	045544	174046				STF AC0,-(SP)	;Save AC0
≠MOV≡≡DVBKSZ≡≡R0≡≥	045546	012700	000012			MOV #DVBKSZ,R0	;Get a device block
≠JSR≡≡PC≡≡GTFREE≡≥	045552	004767	762470			JSR PC,GTFREE	;
≠MOV≡≡R0≡≡R1≡≥	045556	010001				MOV R0,R1	;R1 ← address of device block
≠MOV≡≡R0≡≡SP≡≥	045560	010046				MOV R0,-(SP)	;Save a copy on the stack
≠MOV≡≡MVDCOF≡≡R0≡≥	045562	012700	045644			MOV #MVDCOF,R0	;Pointer to coefficient list
≠JSR≡≡PC≡≡LWHERE≡≥	045566	004777	746226			JSR PC,@LWHERE	;Update the servo blocks
≥								;ignore any failure return.
≠MOV≡≡SP≡≡R0≡≥	045572	012600				MOV (SP)+,R0	;Reclaim device block
≠JSR≡≡PC≡≡RLFREE≡≥	045574	004767	763010			JSR PC,RLFREE	;
≥						;Invalidate all manipulator variables
≠MOV≡≡BHCOFS≡≡R0≡≥	045600	012700	000012			MOV #BHCOFS,R0	;
≠JSR≡≡PC≡≡GETARG≡≥	045604	004767	770452			JSR PC,GETARG	;
≠MOV≡≡R0≡≡R0≡≥	045610	011000				MOV (R0),R0	;
≠JSR≡≡PC≡≡INVLDT≡≥	045612	004767	012560			JSR PC,INVLDT	;
≠MOV≡≡BACOFS≡≡R0≡≥	045616	012700	000010			MOV #BACOFS,R0	;
≠JSR≡≡PC≡≡GETARG≡≥	045622	004767	770434			JSR PC,GETARG	;
≠MOV≡≡R0≡≡R0≡≥	045626	011000				MOV (R0),R0	;
≠JSR≡≡PC≡≡INVLDT≡≥	045630	004767	012542			JSR PC,INVLDT	;
≠.IFNZ≡≡YELLOW≡≥		000000			    .IFNZ YELLOW
≥						MOV #YACOFS,R0	;
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 164
	INTERP PAL[HAL,HE]	PAGE 20.5 	Table of interpreter instructions

≥						JSR PC,GETARG	;
≥						MOV (R0),R0	;
≥						JSR PC,INVLDT	;
≥						MOV #YACOFS,R0	;
≥						JSR PC,GETARG	;
≥						MOV (R0),R0	;
≥						JSR PC,INVLDT	;
≥					    .ENDC
≠LDF≡≡SP≡≡AC0≡≥	045634	172426				LDF (SP)+,AC0	;Restore AC0
≠MOV≡≡SP≡≡R1≡≥	045636	012601				MOV (SP)+,R1	;Restore R1
≠MOV≡≡SP≡≡R0≡≥	045640	012600				MOV (SP)+,R0	;Restore R0
≠RTS≡≡PC≡≥	045642	000207				RTS PC		;
≥					
≠.IFNZ≡≡YELLOW≡≥		000000			    .IFNZ YELLOW
≥					MVDCOF:	YARMSB + YARMSB + BHANDSB + BARMSB
≥						0
≥					    .IFF
≡BHANDS≡≡BHANDS≡≡BARMSB≡≥	045644	000774			MVDCOF:	BHANDSB + BARMSB
≥	045646	000000				0
≥					    .ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 165
	INTERP PAL[HAL,HE]	PAGE 21 	Table of interpreter instructions

≥					;Condition monitors:  CMMAK 
≥					
≠.IFNZ≡≡ONMONS≡≥		000001			.IFNZ ONMONS
≥					
≠COMMEN≡≥				COMMENT ⊗ This is the second version of condition monitors (here
≥				refered to as c-m's).  Hardware-type c-m's are still not ready.  The
≥				checker and the body are the same job in this version; before 10/2/75
≥				they were seperate.  The basic operations are Creation, Enabling,
≥				Disabling, Destruction.  Creation causes a c-m control block to be
≥				set up, and pointed to by the c-m variable.  This block has the
≥					following fields: ⊗
≥					
≡II≠≥		000000				II == 0
≤XX≡≥						XX	CMSEVT	;The event used to awaken the tester upon enabling
≠.IFDF≡≡CMSEVT≡≥						   .IFDF CMSEVT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using CMSEVT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡CMSEVT≠≥		000000				    CMSEVT == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX	CMTEVT	;The event for which this c-m tests, if any
≠.IFDF≡≡CMTEVT≡≥						   .IFDF CMTEVT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using CMTEVT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡CMTEVT≠≥		000002				    CMTEVT == II
≡II≡≡II≠≥		000004				    II == II+2
≤XX≡≥						XX	CMSTAT	;Status bits for the c-m
≠.IFDF≡≡CMSTAT≡≥						   .IFDF CMSTAT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using CMSTAT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡CMSTAT≠≥		000004				    CMSTAT == II
≡II≡≡II≠≥		000006				    II == II+2
≡CMENB≠≥		000001			            CMENB == 1               ;set => enabled
≡CMDES≠≥		000002			            CMDES == 2               ;set => to be destroyed
≡II≡≡CMCBSZ≠≥		000003				CMCBSZ == II/2	;Length in words of a c-m control block.
≥					
≠COMMEN≡≥				COMMENT ⊗ The once-only code of the c-m is sprouted at priority 3 (it
≥				is an interpreter), and after initialization, it waits for the
≥				gronking event CMSEVT.  Enabling signals the event CMSEVT and sets
≥				the enabled bit in CMSTAT.  Disabling resets the enabled bit, and the
≥				c-m will wait on the CMSEVT for future action.  As long as the c-m is
≥				enabled, it periodically wakes up, checks its status bits.  If the
≥				enable bit is reset, the c-m waits for CMSEVT.  Else it checks the
≥				condition.  If it is satisfied, the c-m disables itself and
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 166
	INTERP PAL[HAL,HE]	PAGE 21.1 	Table of interpreter instructions

≥				proceeds to the conclusion and level 1.  (The conclusion should reset
≥				itself to level 0 after all critical activity has been accomplished.)
≥				Otherwise, it reschedules itself.  If the destroy bit should ever be
≥				set in CMSTAT, then the c-m will destroy the event CMSEVT.  Then
≥				it will reclaim the c-m control block and will dismiss, never to
≥				return.  (The pointer to the c-m in the environment should be zeroed
≥					by the destroying angel.). ⊗
≥					
≥					CMMAK:	;Interpreter routine
≥					
≠COMMEN≡≥				COMMENT ⊗ Takes three arguments, the offset of the nascent c-m, the
≥				level-offset of the event that this monitor is to wait on, if any,
≥					and the IPC of the c-m code.  ⊗
≥					
≠MOV≡≡IPC≡≡R4≡≡R2≡≥	045650	017402	000000			MOV @IPC(R4),R2	;R2 ← offset
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	045654	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠ADD≡≡ENV≡≡R4≡≡R2≡≥	045662	066402	000006			ADD ENV(R4),R2	;R2 ← Pointer into environment
≠TST≡≡R2≡≥	045666	005712				TST (R2)	;Already something there?
≠BEQ≡≥	045670	001404				BEQ 1$
≤HALERR≡≥						HALERR CMMMSG	;Yes.  complain.
≠MOV≡≡CMMMSG≡≡SP≡≥	045672	012746	046070			MOV #CMMMSG,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	045676	004777	746110			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≥					
≥						;Make a c-m control block
≠MOV≡≡CMCBSZ≡≡R0≡≥	045702	012700	000003		1$:	MOV #CMCBSZ,R0	;
≠JSR≡≡PC≡≡GTFREE≡≥	045706	004767	762334			JSR PC,GTFREE	;R0 ← LOC[c-m control block]
≠MOV≡≡R0≡≡R2≡≥	045712	010012				MOV R0,(R2)	;Stuff into environment
≤EVMAK≡≥						EVMAK		;
≥	045714	104004				104004
≠MOV≡≡SP≡≡CMSEVT≡≡R0≡≥	045716	012660	000000			MOV (SP)+,CMSEVT(R0)	;Make an event for CMSEVT
≠CLR≡≡CMSTAT≡≡R0≡≥	045722	005060	000004			CLR CMSTAT(R0)	;Disabled, undestroyed
≠CLR≡≡CMTEVT≡≡R0≡≥	045726	005060	000002			CLR CMTEVT(R0)	;Not necessarily ON <event> DO
≠MOV≡≡R0≡≡SP≡≥	045732	010046				MOV R0,-(SP)	;Save LOC[c-m control block]
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	045734	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset of event this c-m waits for.
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	045740	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠TST≡≡R0≡≥	045746	005700				TST R0		;If any
≠BEQ≡≥	045750	001405				BEQ 2$
≠JSR≡≡PC≡≡GETARG≡≥	045752	004767	770304			JSR PC,GETARG	;R0 ← LOC[environment location of event]
≠MOV≡≡SP≡≡R1≡≥	045756	011601				MOV (SP),R1	;R1 ← LOC[c-m control block]
≠MOV≡≡R0≡≡CMTEVT≡≡R1≡≥	045760	011061	000002			MOV (R0),CMTEVT(R1)	;Put the CMTEVT in the c-m control block.
≥					
≥						;Prepare the c-m job
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	045764	017400	000000		2$:	MOV @IPC(R4),R0	;R0 ← IPC of c-m code
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	045770	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠CLR≡≡R1≡≥	045776	005001				CLR R1		;C-m's do not expire with events
≠JSR≡≡PC≡≡SPAWN≡≥	046000	004767	772326			JSR PC,SPAWN	;R0 ← process control block for c-m
≠MOV≡≡PDBR4≡≡PDBSTA≡≡R0≡≡R2≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 167
	INTERP PAL[HAL,HE]	PAGE 21.2 	Table of interpreter instructions

≥	046004	016002	000036		        MOV PDBR4-PDBSTA(R0),R2;R2 ← PR4 = LOC[c-m's interpeter status block]
≠MOV≡≡SP≡≡CMCB≡≡R2≡≥	046010	012662	000020		        MOV (SP)+,CMCB(R2);Stuff CMCB of the c-m
≠MOV≡≡R0≡≡R2≡≥	046014	010002				MOV R0,R2	;R2 ← new process control block 
≥						;Set up the new environment
≠JSR≡≡PC≡≡NEWENV≡≥	046016	004767	767476			JSR PC,NEWENV	;R0 ← LOC[new environment]
≠MOV≡≡ENV≡≡R4≡≡SLINK≡≡R0≡≥	046022	016460	000006	000000		MOV ENV(R4),SLINK(R0)	;Not necessary to set up OLEV, etc.
≠MOV≡≡PDBR4≡≡R2≡≡R1≡≥	046030	016201	000036			MOV PDBR4(R2),R1;
≠MOV≡≡R0≡≡ENV≡≡R1≡≥	046034	010061	000006			MOV R0,ENV(R1)	;
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	046040	016746	763644			      MOV SBEVT,-(SP)
≥	046044	104012				104012
≥					   .ENDC
≠INC≡≡LEV≡≡R1≡≥	046046	005261	000010			INC LEV(R1)	;
≤FORK≡≥						FORK R2,#INTERP,#4;Cause the c-m to be started.  It will go into wait.
≤.ARG≡≥						  .ARG #4
≠.LIF≡≥						    .LIF NB #4
≠MOV≡≡SP≡≥	046052	012746	000004			      MOV #4,-(SP)
≤.ARG≡≥						  .ARG #INTERP
≠.LIF≡≥						    .LIF NB #INTERP
≠MOV≡≡INTERP≡≡SP≡≥	046056	012746	036016			      MOV #INTERP,-(SP)
≤.ARG≡≥						  .ARG R2
≠.LIF≡≥						    .LIF NB R2
≠MOV≡≡R2≡≡SP≡≥	046062	010246				      MOV R2,-(SP)
≥	046064	104002				104002
≥					
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	046066	000207				RTS PC		;Done
≥					
≤ASCIE≡≥					CMMMSG: ASCIE </CMMAK: WILL CREATE EXISTENT CONDITION MONITOR/>
≠.ASCIZ≡≥	046070	   103		
≥	046071	   115		
≥	046072	   115		
≥	046073	   101		
≥	046074	   113		
≥	046075	   072		
≥	046076	   040		
≥	046077	   127		
≥	046100	   111		
≥	046101	   114		
≥	046102	   114		
≥	046103	   040		
≥	046104	   103		
≥	046105	   122		
≥	046106	   105		
≥	046107	   101		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 168
	INTERP PAL[HAL,HE]	PAGE 21.3 	Table of interpreter instructions

≥	046110	   124		
≥	046111	   105		
≥	046112	   040		
≥	046113	   105		
≥	046114	   130		
≥	046115	   111		
≥	046116	   123		
≥	046117	   124		
≥	046120	   105		
≥	046121	   116		
≥	046122	   124		
≥	046123	   040		
≥	046124	   103		
≥	046125	   117		
≥	046126	   116		
≥	046127	   104		
≥	046130	   111		
≥	046131	   124		
≥	046132	   111		
≥	046133	   117		
≥	046134	   116		
≥	046135	   040		
≥	046136	   115		
≥	046137	   117		
≥	046140	   116		
≥	046141	   111		
≥	046142	   124		
≥	046143	   117		
≥	046144	   122		
≥	046145	   000		
≥					       .ASCIZ /CMMAK: WILL CREATE EXISTENT CONDITION MONITOR/
≠.EVEN≡≥		046146			       .EVEN
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 169
	INTERP PAL[HAL,HE]	PAGE 22 	Table of interpreter instructions

≥					;  CMENBL, CMDSBL, CMDEST, CMTRIG, CMSKED, CMUNCR
≥					
≤ASCIE≡≥					CMNEMS:	ASCIE </TRYING TO TREAT NON-EXISTENT EVENT/>
≠.ASCIZ≡≥	046146	   124		
≥	046147	   122		
≥	046150	   131		
≥	046151	   111		
≥	046152	   116		
≥	046153	   107		
≥	046154	   040		
≥	046155	   124		
≥	046156	   117		
≥	046157	   040		
≥	046160	   124		
≥	046161	   122		
≥	046162	   105		
≥	046163	   101		
≥	046164	   124		
≥	046165	   040		
≥	046166	   116		
≥	046167	   117		
≥	046170	   116		
≥	046171	   055		
≥	046172	   105		
≥	046173	   130		
≥	046174	   111		
≥	046175	   123		
≥	046176	   124		
≥	046177	   105		
≥	046200	   116		
≥	046201	   124		
≥	046202	   040		
≥	046203	   105		
≥	046204	   126		
≥	046205	   105		
≥	046206	   116		
≥	046207	   124		
≥	046210	   000		
≥					       .ASCIZ /TRYING TO TREAT NON-EXISTENT EVENT/
≠.EVEN≡≥		046212			       .EVEN
≥					
≥					CMENBL: ;Interpeter routine
≥					;  One argument, a level-offset pair for the c-m to enable.
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	046212	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	046216	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	046224	004767	770032			JSR PC,GETARG	;R0 ← pointer into environment
≠MOV≡≡R0≡≡R0≡≥	046230	011000				MOV (R0),R0	;R0 ← pointer to c-m control block.
≠BEQ≡≡CMDERR≡≥	046232	001424				BEQ CMDERR	;If none, then error
≠BIS≡≡CMENB≡≡CMSTAT≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 170
	INTERP PAL[HAL,HE]	PAGE 22.1 	Table of interpreter instructions

≥	046234	052760	000001	000004		BIS #CMENB,CMSTAT(R0)	;Set the enable bit
≤EVSIG≡≥						EVSIG CMSEVT(R0)	;Gronk the c-m
≤.ARG≡≥						  .ARG CMSEVT(R0)
≠.LIF≡≥						    .LIF NB CMSEVT(R0)
≠MOV≡≡CMSEVT≡≡R0≡≡SP≡≥	046242	016046	000000			      MOV CMSEVT(R0),-(SP)
≥	046246	104012				104012
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	046250	000207				RTS PC		;Done
≥					
≥					CMDSBL:	;Interpreter routine
≥					;  One argument, a level-offset pair for the c-m to disable.
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	046252	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	046256	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	046264	004767	767772			JSR PC,GETARG	;R0 ← pointer into environment
≠MOV≡≡R0≡≡R0≡≥	046270	011000				MOV (R0),R0	;R0 ← pointer to c-m control block.
≠BEQ≡≡CMDERR≡≥	046272	001404				BEQ CMDERR	;If none, then error
≠BIC≡≡CMENB≡≡CMSTAT≡≡R0≡≥	046274	042760	000001	000004		BIC #CMENB,CMSTAT(R0)	;Clear the enable bit
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	046302	000207				RTS PC		;Done
≤HALERR≡≥					CMDERR:	HALERR CMNEMS	;
≠MOV≡≡CMNEMS≡≡SP≡≥	046304	012746	046146			MOV #CMNEMS,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	046310	004777	745476			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤SCC≡≥						SCC		;Set condition code
≥					;	MOV #2,R0	;Set condition code.  Not used right now. (maybe use TST PC)
≠RTS≡≡PC≡≥	046314	000207				RTS PC		;
≥					
≥					CMDEST:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Argument list.  Each is an offset for the c-m to destroy. 
≥					The list is terminated with a zero entry.  ⊗
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	046316	017400	000000			MOV @IPC(R4),R0	;R0 ← offset
≠BEQ≡≥	046322	001417				BEQ 1$		;If 0, then done
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	046324	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠ADD≡≡ENV≡≡R4≡≡R0≡≥	046332	066400	000006			ADD ENV(R4),R0	;R0 ← pointer into environment
≠MOV≡≡R0≡≡R1≡≥	046336	011001				MOV (R0),R1	;R1 ← LOC[c-m control block]
≠BEQ≡≡CMDERR≡≥	046340	001761				BEQ CMDERR	;If none, then error
≠BIS≡≡CMDES≡≡CMSTAT≡≡R1≡≥	046342	052761	000002	000004		BIS #CMDES,CMSTAT(R1)	;Set the destroy bit
≤EVKIL≡≥						EVKIL CMSEVT(R1);Destroy the event.  That ought to wake him up!
≤.ARG≡≥						  .ARG CMSEVT(R1)
≠.LIF≡≥						    .LIF NB CMSEVT(R1)
≠MOV≡≡CMSEVT≡≡R1≡≡SP≡≥	046350	016146	000000			      MOV CMSEVT(R1),-(SP)
≥	046354	104006				104006
≠CLR≡≡R0≡≥	046356	005010				CLR (R0)	;Remove c-m from environment
≠BR≡≡CMDEST≡≥	046360	000756				BR CMDEST	;Go do the next one.
≤BMPIPC≡≥					1$:	BMPIPC		;Bump IPC the last time
≠ADD≡≡IPC≡≡R4≡≥	046362	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤CCC≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 171
	INTERP PAL[HAL,HE]	PAGE 22.2 	Table of interpreter instructions

≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	046370	000207				RTS PC		;Done
≥					
≥					CMTRIG:	;Interpeter routine
≠COMMEN≡≥				COMMENT ⊗ Should be executed only from a c-m.  Sets the priority to 1
≥					and disables the checker.  ⊗
≥					
≠MOV≡≡CMCB≡≡R4≡≡R0≡≥	046372	016400	000020			MOV CMCB(R4),R0	;
≤EVTST≡≥					1$:	EVTST CMSEVT(R0);Eat all signals enabling the checker.
≤.ARG≡≥						  .ARG CMSEVT(R0)
≠.LIF≡≥						    .LIF NB CMSEVT(R0)
≠MOV≡≡CMSEVT≡≡R0≡≡SP≡≥	046376	016046	000000			      MOV CMSEVT(R0),-(SP)
≥	046402	104022				104022
≠BCC≡≥	046404	103374				BCC 1$
≠BIC≡≡CMENB≡≡CMSTAT≡≡R0≡≥	046406	042760	000001	000004		BIC #CMENB,CMSTAT(R0)	;Clear the enable bit
≠MOV≡≡PCB≡≡R4≡≡R0≡≥	046414	016400	000014			MOV PCB(R4),R0	;
≠CLR≡≡R0≡≥	046420	005060	000002			CLR 2(R0)	;Clear word 1 of process control block to reset nominal
≥								;  priority to 0.
≤SETPRI≡≥						SETPRI #1	;Set the priority to 1
≤.ARG≡≥						  .ARG #1
≠.LIF≡≥						    .LIF NB #1
≠MOV≡≡SP≡≥	046424	012746	000001			      MOV #1,-(SP)
≥	046430	104020				104020
≠TST≡≡SP≡≥	046432	005726				TST (SP)+	;Discard old priority
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	046434	000207				RTS PC		;Done
≥					
≥					CMSKED:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Goes to sleep a while (currently, 100 milliseconds).  Upon
≥				awakening, checks the status bits of this checker, and either
≥					dismisses, waits, or returns.  ⊗
≥					
≤SETPRI≡≥						SETPRI #3	;In case the conclusion left it at 1 or 0.
≤.ARG≡≥						  .ARG #3
≠.LIF≡≥						    .LIF NB #3
≠MOV≡≡SP≡≥	046436	012746	000003			      MOV #3,-(SP)
≥	046442	104020				104020
≠TST≡≡SP≡≥	046444	005726				TST (SP)+	;Flush old priority
≠MOV≡≡IPC≡≡R4≡≡SP≡≥	046446	017446	000000			MOV @IPC(R4),-(SP)	;Waiting interval
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	046452	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤SLEEP≡≥						SLEEP 		;Sleep a while
≤.ARG≡≥						  .ARG 
≠.LIF≡≥						    .LIF NB 
≥						      MOV ,-(SP)
≥	046460	104014				104014
≠MOV≡≡CMCB≡≡R4≡≡R0≡≥	046462	016400	000020			MOV CMCB(R4),R0	;R0 ← c-m control block
≠BIT≡≡CMDES≡≡CMSTAT≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 172
	INTERP PAL[HAL,HE]	PAGE 22.3 	Table of interpreter instructions

≥	046466	032760	000002	000004	1$:	BIT #CMDES,CMSTAT(R0)	;Destroy bit set?
≠BEQ≡≥	046474	001407				BEQ 3$		;No
≤EVKIL≡≥						EVKIL CMSEVT(R0);Yes.  Kill the triggering event.
≤.ARG≡≥						  .ARG CMSEVT(R0)
≠.LIF≡≥						    .LIF NB CMSEVT(R0)
≠MOV≡≡CMSEVT≡≡R0≡≡SP≡≥	046476	016046	000000			      MOV CMSEVT(R0),-(SP)
≥	046502	104006				104006
≠JSR≡≡PC≡≡RLFREE≡≥	046504	004767	762100		2$:	JSR PC,RLFREE	;Return the c-m control block
≠JMP≡≡TERMIN≡≥	046510	000167	772252			JMP TERMINATE	;Use the interpeter terminate routine.
≠BIT≡≡CMENB≡≡CMSTAT≡≡R0≡≥	046514	032760	000001	000004	3$:	BIT #CMENB,CMSTAT(R0)	;Enable bit set?
≠BNE≡≥	046522	001005				BNE 4$		;Yes.
≤EVWAIT≡≥						EVWAIT CMSEVT(R0);No.  Wait until signaled by the enabler
≤.ARG≡≥						  .ARG CMSEVT(R0)
≠.LIF≡≥						    .LIF NB CMSEVT(R0)
≠MOV≡≡CMSEVT≡≡R0≡≡SP≡≥	046524	016046	000000			      MOV CMSEVT(R0),-(SP)
≥	046530	104010				104010
≠BCS≡≥	046532	103764				BCS 2$		;If the enabling event died, so must we.
≠BR≡≥	046534	000754				BR  1$		;Else start from the awakening point.
≠MOV≡≡CMTEVT≡≡R0≡≡R1≡≥	046536	016001	000002		4$:	MOV CMTEVT(R0),R1	;R1 ← event to test for
≠BEQ≡≥	046542	001411				BEQ 5$		;If any
≤EVWAIT≡≥						EVWAIT R1	;Wait for event to happen
≤.ARG≡≥						  .ARG R1
≠.LIF≡≥						    .LIF NB R1
≠MOV≡≡R1≡≡SP≡≥	046544	010146				      MOV R1,-(SP)
≥	046546	104010				104010
≠BIT≡≡CMENB≡≡CMSTAT≡≡R0≡≥	046550	032760	000001	000004		BIT #CMENB,CMSTAT(R0)	;Still enabled?
≠BNE≡≥	046556	001003				BNE 5$		;Yes.  May exit.
≤EVSIG≡≥						EVSIG R1	;Oops, we were disabled!  Resignal the event.
≤.ARG≡≥						  .ARG R1
≠.LIF≡≥						    .LIF NB R1
≠MOV≡≡R1≡≡SP≡≥	046560	010146				      MOV R1,-(SP)
≥	046562	104012				104012
≠BR≡≥	046564	000740				BR 1$		;And try again.
≤CCC≡≥					5$:	CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	046566	000207				RTS PC		;Done
≥					
≥					CMUNCR:	;Interpreter routine.  
≠COMMEN≡≥					COMMENT ⊗  Used in body of c-m.  Starts uncritical section.  ⊗
≠MOV≡≡PCB≡≡R4≡≡R0≡≥	046570	016400	000014			MOV PCB(R4),R0	;
≠CLR≡≡R0≡≥	046574	005060	000002			CLR 2(R0)	;Clear word 1 of process control block to reset nominal
≥								;  priority to 0.
≤SETPRI≡≥						SETPRI #0	;Set the priority to 0
≤.ARG≡≥						  .ARG #0
≠.LIF≡≥						    .LIF NB #0
≠MOV≡≡SP≡≥	046600	012746	000000			      MOV #0,-(SP)
≥	046604	104020				104020
≠TST≡≡SP≡≥	046606	005726				TST (SP)+	;Flush old priority
≤CCC≡≥						CCC		;Clear condition code
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 173
	INTERP PAL[HAL,HE]	PAGE 22.4 	Table of interpreter instructions

≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	046610	000207				RTS PC		;Done
≥					
≥					.ENDC  ; End of the ONMON material
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 174
	INTERP PAL[HAL,HE]	PAGE 23 	Table of interpreter instructions

≥					;Force expressions.  Data structures. TABOFS, FMBLK, MAKFORCE, DESFORCE
≥					
≠COMMEN≡≥				COMMENT ⊗ Certain tables are available via COMTAB entries.  LERRPTR
≥				points to the table ERRPTR of 16 words, one for each servo, which
≥				points at the current error torques.  LTHPTR points at the table THPTR
≥				of 16 words, one for each servo, which points at the current joint
≥					angles.  ⊗
≥					
≥					TABOFS:	
≠COMMEN≡≥				COMMENT ⊗ R0 = Mechanism bit.  Returns table offset (in bytes) in R0.
≥					For example, if the mechanism is BARM, the OFBARM is returned.  ⊗
≠BIT≡≡YARM≡≡R0≡≥	046612	032700	000001			BIT #YARM,R0	;Is it this mechanism?
≠BEQ≡≥	046616	001403				BEQ 1$		;No
≠MOV≡≡OFYARM≡≡R0≡≥	046620	012700	000000			MOV #OFYARM,R0	;Yes.  Load up proper offset
≠RTS≡≡PC≡≥	046624	000207				RTS PC		; and return.
≠BIT≡≡YHAND≡≡R0≡≥	046626	032700	000002		1$:	BIT #YHAND,R0	;Is it this mechanism?
≠BEQ≡≥	046632	001403				BEQ 2$		;No
≠MOV≡≡OFYHAN≡≡R0≡≥	046634	012700	000014			MOV #OFYHAND,R0	;Yes.  Load up proper offset
≠RTS≡≡PC≡≥	046640	000207				RTS PC		; and return.
≠BIT≡≡BARM≡≡R0≡≥	046642	032700	000004		2$:	BIT #BARM,R0	;Is it this mechanism?
≠BEQ≡≥	046646	001403				BEQ 3$		;No
≠MOV≡≡OFBARM≡≡R0≡≥	046650	012700	000016			MOV #OFBARM,R0	;Yes.  Load up proper offset
≠RTS≡≡PC≡≥	046654	000207				RTS PC		; and return.
≠BIT≡≡BHAND≡≡R0≡≥	046656	032700	000010		3$:	BIT #BHAND,R0	;Is it this mechanism?
≠BEQ≡≥	046662	001403				BEQ 4$		;No
≠MOV≡≡OFBHAN≡≡R0≡≥	046664	012700	000032			MOV #OFBHAND,R0	;Yes.  Load up proper offset
≠RTS≡≡PC≡≥	046670	000207				RTS PC		; and return.
≤HALERR≡≥					4$:	HALERR TABMES	;Illegal
≠MOV≡≡TABMES≡≡SP≡≥	046672	012746	046706			MOV #TABMES,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	046676	004777	745110			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠CLR≡≡R0≡≥	046702	005000				CLR R0		;
≠RTS≡≡PC≡≥	046704	000207				RTS PC		;
≤ASCIE≡≥					TABMES:	ASCIE </ILLEGAL MECHANISM/>
≠.ASCIZ≡≥	046706	   111		
≥	046707	   114		
≥	046710	   114		
≥	046711	   105		
≥	046712	   107		
≥	046713	   101		
≥	046714	   114		
≥	046715	   040		
≥	046716	   115		
≥	046717	   105		
≥	046720	   103		
≥	046721	   110		
≥	046722	   101		
≥	046723	   116		
≥	046724	   111		
≥	046725	   123		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 175
	INTERP PAL[HAL,HE]	PAGE 23.1 	Table of interpreter instructions

≥	046726	   115		
≥	046727	   000		
≥					       .ASCIZ /ILLEGAL MECHANISM/
≠.EVEN≡≥		046730			       .EVEN
≥					
≥					;   Force monitor block (FMBLK)
≥					
≡II≠≥		000000				II == 0
≡II≡≡FMFOMO≠≥		000000				FMFOMO == II		;Force - moment array.  20 words.
≥					          ;WORD   0,0     	  force component in X direction
≥					          ;WORD   0,0     	  ditto for Y
≥					          ;WORD   0,0     	  Z
≥					          ;WORD   40200,0 	  (1.0) scaling factor, not used
≥					          ;WORD   0,0     	  moment component in X direction
≥					          ;WORD   0,0     	  Y
≥					          ;WORD   0,0     	  Z
≥					          ;WORD   40200,0 	  1.0
≡II≡≡II≠≥		000040					II == II + 40	
≡II≡≡FMRETO≠≥		000040				FMRETO == II		;Reaction - torque array.  14 words.
≡II≡≡II≠≥		000070					II == II + 30
≡II≡≡FMJOAN≠≥		000070				FMJOAN == II		;Joint angle array.  14 words.
≡II≡≡II≠≥		000120					II == II + 30	
≡II≡≡FMMECH≠≥		000120				FMMECH == II 		;Arm involved:  mechanism bits
≡II≡≡II≠≥		000122					II == II + 2
≡II≡≡FMSCAL≠≥		000122				FMSCAL == II		;Scale factor (sum of squares of RETO)
≡II≡≡II≠≥		000126					II == II + 4
≡II≡≡FMMODE≠≥		000126				FMMODE == II		;Mode bits
≡FMKIL≠≥		000002				  FMKIL == 2		  ;set if this FM should go away.
≡FMBEX≠≥		000004				  FMBEX == 4		  ;set if background job 
≥									  ; (fills reaction-torque array) exists
≡FMFEX≠≥		000010				  FMFEX == 10		  ;set by GETFORCE, reset by MAKRT
≡II≡≡II≠≥		000130					II == II + 2	
≡II≡≡FMSIZ≠≥		000054				FMSIZ == II/2		;Length in words of force monitor block
≥					
≥					MAKFORCE:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ Prepares the force variable needed to compute forces.  The
≥				offset is the first argument, and the mechanism number is the second
≥				argument.  Sets the environment pointing to a new force monitor
≥				block, whose force-moment array it fills from the two top elements of
≥				the stack, which are then popped: the first is the force vector, the
≥				second is the moment vector. These are both in hand coordinates. This
≥				routine does not load the reaction-torque array or the joint angle
≥					array. ⊗
≠MOV≡≡FMSIZ≡≡R0≡≥	046730	012700	000054			MOV #FMSIZ,R0		;
≠JSR≡≡PC≡≡GTFREE≡≥	046734	004767	761306			JSR PC,GTFREE		;R0 ← LOC[new fmblock]
≠CLR≡≡FMMODE≡≡R0≡≥	046740	005060	000126			CLR FMMODE(R0)		;Reset all mode bits
≠MOV≡≡IPC≡≡R4≡≡R1≡≥	046744	017401	000000			MOV @IPC(R4),R1		;R1 ← offset
≤BMPIPC≡≥						BMPIPC			;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	046750	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠BIC≡≡R1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 176
	INTERP PAL[HAL,HE]	PAGE 23.2 	Table of interpreter instructions

≥	046756	042701	177400			BIC #177400,R1		;Remove level info.
≠ADD≡≡ENV≡≡R4≡≡R1≡≥	046762	066401	000006			ADD ENV(R4),R1		;R1 ← LOC[place in environment]
≠MOV≡≡R0≡≡R1≡≥	046766	010011				MOV R0,(R1)		;Stow away the pointer to the new fmblock
≠MOV≡≡IPC≡≡R4≡≡FMMECH≡≡R0≡≥	046770	017460	000000	000120		MOV @IPC(R4),FMMECH(R0)	;Stow away the mechanism in the new fmblock
≤BMPIPC≡≥						BMPIPC			;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	046776	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠MOV≡≡R0≡≡SP≡≥	047004	010046				MOV R0,-(SP)		;Stack LOC[new fmblock]
≠JSR≡≡PC≡≡NOCMP≡≥	047006	004767	764344			JSR PC,NOCMP		;Don't compact for a bit
≠MOV≡≡R3≡≡R0≡≥	047012	012300				MOV (R3)+,R0		;Swap LOC[moment vector] & LOC[force vector]
≠MOV≡≡R3≡≡R3≡≥	047014	011343				MOV (R3),-(R3)
≠MOV≡≡R0≡≡R3≡≥	047016	010063	000002			MOV R0,2(R3)
≠JSR≡≡PC≡≡UNITV≡≥	047022	004767	773450			JSR PC,UNITV		;Normalize the force vector
≠MOV≡≡R3≡≡R2≡≥	047026	012302				MOV (R3)+,R2		;R2 ← LOC[force vector]
≠MOV≡≡R3≡≡R1≡≥	047030	012301				MOV (R3)+,R1		;R1 ← LOC[moment vector]
≠MOV≡≡SP≡≡R0≡≥	047032	012600				MOV (SP)+,R0		;Restore R0 ← LOC[new fmblock]
≠ADD≡≡FMFOMO≡≡R0≡≥	047034	062700	000000			ADD #FMFOMO,R0		;R0 ← LOC[force-moment vector]
≠MOV≡≡R3≡≡SP≡≥	047040	010346				MOV R3,-(SP)		;Save R3
≠MOV≡≡R3≡≥	047042	012703	000010			MOV #10,R3		;R3 ← count: how many words to transfer
≠MOV≡≡R2≡≡R0≡≥	047046	012220			1$:	MOV (R2)+,(R0)+		;transfer force vector
≠SOB≡≡R3≡≥	047050	077302				SOB R3,1$		;repeat
≠MOV≡≡R3≡≥	047052	012703	000006			MOV #6,R3		;R3 ← count: how many words to transfer
≠MOV≡≡R1≡≡R0≡≥	047056	012120			2$:	MOV (R1)+,(R0)+		;transfer moment vector
≠SOB≡≡R3≡≥	047060	077302				SOB R3,2$		;repeat
≠MOV≡≡ONE≡≡R0≡≥	047062	016720	002244			MOV ONE,(R0)+		;
≠CLR≡≡R0≡≥	047066	005010				CLR (R0)		;
≠MOV≡≡SP≡≡R3≡≥	047070	012603				MOV (SP)+,R3		;Restore R3
≠JSR≡≡PC≡≡YESCMP≡≥	047072	004767	764302			JSR PC,YESCMP		;OK to compact now
≤CCC≡≥						CCC			;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	047076	000207				RTS PC			;Return
≥					
≥					DESFORCE:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ One argument: the level-offset of the force block to
≥				destroy.  Reclaims the block only if there is no MAKRT job;
≥					otherwise, lets that job reclaim the block.  ⊗
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	047100	017400	000000			MOV @IPC(R4),R0		;R0 ← level-offset
≤BMPIPC≡≥						BMPIPC			;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	047104	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	047112	004767	767144			JSR PC,GETARG		;R0 ← LOC[environment point]
≠MOV≡≡R0≡≡R2≡≥	047116	010002				MOV R0,R2		;For safekeeping
≠MOV≡≡R0≡≡R0≡≥	047120	011000				MOV (R0),R0		;R0 ← LOC[fm control block]
≠BEQ≡≥	047122	001414				BEQ 3$			;If any
≠CLR≡≡R2≡≥	047124	005012				CLR (R2)		;Remove mention in the environment
≠BIT≡≡FMBEX≡≡FMMODE≡≡R0≡≥	047126	032760	000004	000126		BIT #FMBEX,FMMODE(R0)	;Is there a MAKRT job?
≠BNE≡≥	047134	001004				BNE 1$			;No.
≠BIS≡≡FMKIL≡≡FMMODE≡≡R0≡≥	047136	052760	000002	000126		BIS #FMKIL,FMMODE(R0)	;Yes.  Set the destroy bit.
≠BR≡≥	047144	000402				BR 2$
≠JSR≡≡PC≡≡RLFREE≡≥	047146	004767	761436		1$:	JSR PC,RLFREE		;Reclaim the control block.
≤CCC≡≥					2$:	CCC			;Clear condition code
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 177
	INTERP PAL[HAL,HE]	PAGE 23.3 	Table of interpreter instructions

≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	047152	000207				RTS PC			;Done
≤HALERR≡≥					3$:	HALERR DESMSG		;Complain
≠MOV≡≡DESMSG≡≡SP≡≥	047154	012746	047166			MOV #DESMSG,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	047160	004777	744626			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤SCC≡≥						SCC			;Set condition code
≥					;	MOV #2,R0	;Set condition code.  Not used right now. (maybe use TST PC)
≠RTS≡≡PC≡≥	047164	000207				RTS PC			;Done
≤ASCIE≡≥					DESMSG:	ASCIE </CANT DESTROY NON-EXISTENT FORCE MONITOR/>
≠.ASCIZ≡≥	047166	   103		
≥	047167	   101		
≥	047170	   116		
≥	047171	   124		
≥	047172	   040		
≥	047173	   104		
≥	047174	   105		
≥	047175	   123		
≥	047176	   124		
≥	047177	   122		
≥	047200	   117		
≥	047201	   131		
≥	047202	   040		
≥	047203	   116		
≥	047204	   117		
≥	047205	   116		
≥	047206	   055		
≥	047207	   105		
≥	047210	   130		
≥	047211	   111		
≥	047212	   123		
≥	047213	   124		
≥	047214	   105		
≥	047215	   116		
≥	047216	   124		
≥	047217	   040		
≥	047220	   106		
≥	047221	   117		
≥	047222	   122		
≥	047223	   103		
≥	047224	   105		
≥	047225	   040		
≥	047226	   115		
≥	047227	   117		
≥	047230	   116		
≥	047231	   111		
≥	047232	   124		
≥	047233	   117		
≥	047234	   122		
≥	047235	   000		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 178
	INTERP PAL[HAL,HE]	PAGE 23.4 	Table of interpreter instructions

≥					       .ASCIZ /CANT DESTROY NON-EXISTENT FORCE MONITOR/
≠.EVEN≡≥		047236			       .EVEN
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 179
	INTERP PAL[HAL,HE]	PAGE 24 	Table of interpreter instructions

≥					;  GETFORCE, MAKRT
≥					
≥					GETFORCE:	;Interpreter routine
≠COMMEN≡≥				COMMENT ⊗ One argument, the level-offset of the force variable, which
≥				points to the force monitor block.  It is assumed that the reaction
≥				torque array is already prepared.  Calculates the current force on
≥					the arm (it is a scalar) and places it on the stack.  ⊗
≥					
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	047236	017400	000000			MOV @IPC(R4),R0		;R0 ← Level-offset
≤BMPIPC≡≥						BMPIPC			;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	047242	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	047250	004767	767006			JSR PC,GETARG		;R0 ← LOC[LOC[fmblock]]
≠MOV≡≡R0≡≡R2≡≥	047254	011002				MOV (R0),R2		;R2 ← LOC[fmblock]
≠BEQ≡≥	047256	001511				BEQ 4$			;If any
≠CLRF≡≡AC0≡≥	047260	170400				CLRF AC0		;AC0 is the result force.  Set to 0.
≠BIS≡≡FMFEX≡≡FMMODE≡≡R2≡≥	047262	052762	000010	000126		BIS #FMFEX,FMMODE(R2)	;Imply that we are still awake.
≠BIT≡≡FMBEX≡≡FMMODE≡≡R2≡≥	047270	032762	000004	000126		BIT #FMBEX,FMMODE(R2)	;Is there a MAKRT job?
≠BNE≡≥	047276	001042				BNE 1$			;Yes.
≥						;Make a job for the MAKRT routine.  Put LOC[fmblock] in its R0.
≠BIS≡≡FMBEX≡≡FMMODE≡≡R2≡≥	047300	052762	000004	000126		BIS #FMBEX,FMMODE(R2)	;Say that the MAKRT job exists.
≠MOV≡≡R0≡≥	047306	012700	000210			MOV #210,R0		;Room for process descriptor
≠JSR≡≡PC≡≡GTFREE≡≥	047312	004767	760730			JSR PC,GTFREE		;R0 ← LOC[new process descriptor]
≠MOV≡≡R2≡≡PDBR0≡≡R0≡≥	047316	010260	000026			MOV R2,PDBR0(R0)	;Put LOC[fmblock] in its new R0
≠MOV≡≡R0≡≡PDBR1≡≡R0≡≥	047322	010060	000030			MOV R0,PDBR1(R0)	;Put LOC[PCB] in its new R1
≠MOV≡≡UFPUSE≡≡UGRSAV≡≡PDBSTA≡≡R0≡≥	047326	012760	104000	000000		MOV #UFPUSE+UGRSAV,PDBSTA(R0);Use floating point, use saved registers.
≠MOV≡≡UPDLEN≡≡R0≡≥	047334	012760	000420	000002		MOV #420,UPDLEN(R0)	;Length of PCB
≠MOV≡≡PCB≡≡R4≡≡R1≡≥	047342	016401	000014			MOV PCB(R4),R1		;Copy the mapping stuff
≠MOV≡≡UIMAP≡≡R1≡≡UIMAP≡≡R0≡≥	047346	016160	000022	000022		MOV UIMAP(R1),UIMAP(R0)	;Map stuff
≠MOV≡≡UDMAP≡≡R1≡≡UDMAP≡≡R0≡≥	047354	016160	000024	000024		MOV UDMAP(R1),UDMAP(R0)	;Map stuff
≥						;do something about the stack pointer
≠MOV≡≡MAKRT≡≡PDBPC≡≡R0≡≥	047362	012760	047534	000016		MOV #MAKRT,PDBPC(R0)	;Store away the new PC
≤FORK≡≥						FORK R0,#MAKRT,#3	;Cause the new process to be started.
≤.ARG≡≥						  .ARG #3
≠.LIF≡≥						    .LIF NB #3
≠MOV≡≡SP≡≥	047370	012746	000003			      MOV #3,-(SP)
≤.ARG≡≥						  .ARG #MAKRT
≠.LIF≡≥						    .LIF NB #MAKRT
≠MOV≡≡MAKRT≡≡SP≡≥	047374	012746	047534			      MOV #MAKRT,-(SP)
≤.ARG≡≥						  .ARG R0
≠.LIF≡≥						    .LIF NB R0
≠MOV≡≡R0≡≡SP≡≥	047400	010046				      MOV R0,-(SP)
≥	047402	104002				104002
≠MOV≡≡FMMECH≡≡R2≡≡R0≡≥	047404	016200	000120		1$:	MOV FMMECH(R2),R0	;R0 ← mechanism
≠JSR≡≡PC≡≡TABOFS≡≥	047410	004767	777176			JSR PC,TABOFS		;R0 ← offset into joint error table
≠ADD≡≡LERRPT≡≡R0≡≥	047414	066700	744404			ADD LERRPTR,R0		;R0 ← LOC[proper place in error torque]
≠MOV≡≡R2≡≡R1≡≥	047420	010201				MOV R2,R1		;
≠ADD≡≡FMRETO≡≡R1≡≥	047422	062701	000040			ADD #FMRETO,R1		;R1 ← LOC[reaction torque array]
≠MOV≡≡R3≡≡SP≡≥	047426	010346				MOV R3,-(SP)		;Save R3
≠BIT≡≡AHAND≡≡FMMECH≡≡R2≡≥	047430	032762	000012	000120		BIT #AHAND,FMMECH(R2)	;Is it a hand?
≠BEQ≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 180
	INTERP PAL[HAL,HE]	PAGE 24.1 	Table of interpreter instructions

≥	047436	001403				BEQ 2$			;No
≠MOV≡≡R3≡≥	047440	012703	000001			MOV #1,R3		;Yes, R3 ← 2 ← count of joints
≠BR≡≥	047444	000402				BR  3$
≠MOV≡≡R3≡≥	047446	012703	000006		2$:	MOV #6,R3		;R3 ← 6 ← count of joints
≠LDF≡≡R1≡≡AC1≡≥	047452	172521			3$:	LDF (R1)+,AC1		;AC1 ← reaction torque
≠MULF≡≡R0≡≡AC1≡≥	047454	171130				MULF @(R0)+,AC1		;  * joint error
≠ADDF≡≡AC1≡≡AC0≡≥	047456	172001				ADDF AC1,AC0		;cumulate
≠SOB≡≡R3≡≥	047460	077304				SOB  R3,3$		;repeat
≠DIVF≡≡FMSCAL≡≡R2≡≡AC0≡≥	047462	174462	000122			DIVF FMSCAL(R2),AC0	;Normalise
≠MOV≡≡SP≡≡R3≡≥	047466	012603				MOV (SP)+,R3		;Restore R3
≠JSR≡≡PC≡≡GETSCA≡≥	047470	004767	766730			JSR PC,GETSCA		;R0 ← -(R3) ← LOC[new scalar block]
≠STF≡≡AC0≡≡R3≡≥	047474	174073	000000			STF AC0,@(R3)		;Store answer
≤CCC≡≥						CCC			;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	047500	000207				RTS PC			;Return
≤HALERR≡≥					4$:	HALERR GTFMES		;Complain
≠MOV≡≡GTFMES≡≡SP≡≥	047502	012746	047514			MOV #GTFMES,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	047506	004777	744300			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤SCC≡≥						SCC			;Set condition code
≥					;	MOV #2,R0	;Set condition code.  Not used right now. (maybe use TST PC)
≠RTS≡≡PC≡≥	047512	000207				RTS PC			;Return
≤ASCIE≡≥					GTFMES:	ASCIE </NO FORCE BLOCK/>
≠.ASCIZ≡≥	047514	   116		
≥	047515	   117		
≥	047516	   040		
≥	047517	   106		
≥	047520	   117		
≥	047521	   122		
≥	047522	   103		
≥	047523	   105		
≥	047524	   040		
≥	047525	   102		
≥	047526	   114		
≥	047527	   117		
≥	047530	   103		
≥	047531	   113		
≥	047532	   000		
≥					       .ASCIZ /NO FORCE BLOCK/
≠.EVEN≡≥		047534			       .EVEN
≥					
≥					MAKRT:		
≠COMMEN≡≥				COMMENT ⊗ This is a separate job which periodically reestablishes the
≥				reaction torque array and the scale factor for a fmblock.  When first
≥				called, the location of the fmblock is in R0, and the location of the
≥				PCB for the process is in R1.  Makes sure that the force is still
≥				needed (that is, that the FMKIL bit is off and the FMFEX is on) and
≥				then sets up the array.  Sleeps for half a second and tries it again.
≥				If the FMKIL is on, then the fmblock and PCB are returned to free
≥				storage and the process terminates.  If FMFEX is off, then FMBEX is
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 181
	INTERP PAL[HAL,HE]	PAGE 24.2 	Table of interpreter instructions

≥				turned off as well, the PCB is returned to free storage, and the
≥					process terminates.  ⊗
≠MOV≡≡R1≡≡SP≡≥	047534	010146				MOV R1,-(SP)		;Save the PCB address
≠MOV≡≡R0≡≡R4≡≥	047536	010004				MOV R0,R4		;R4 ← LOC[fmblock]
≠BIT≡≡FMKIL≡≡FMMODE≡≡R4≡≥	047540	032764	000002	000126	1$:	BIT #FMKIL,FMMODE(R4)	;Kill bit set?
≠BNE≡≥	047546	001104				BNE 7$			;Yes.
≠BIT≡≡FMFEX≡≡FMMODE≡≡R4≡≥	047550	032764	000010	000126		BIT #FMFEX,FMMODE(R4)	;Has GETFORCE been called recently?
≠BNE≡≥	047556	001004				BNE 2$			;Yes.
≠BIC≡≡FMBEX≡≡FMMODE≡≡R4≡≥	047560	042764	000004	000126		BIC #FMBEX,FMMODE(R4)	;No; say we are leaving.
≠BR≡≥	047566	000477				BR 8$			;Leave
≠BIC≡≡FMFEX≡≡FMMODE≡≡R4≡≥	047570	042764	000010	000126	2$:	BIC #FMFEX,FMMODE(R4)	;Reset the recency bit.
≠MOV≡≡FMMECH≡≡R4≡≡R0≡≥	047576	016400	000120			MOV FMMECH(R4),R0	;R0 ← mechanism
≠JSR≡≡PC≡≡TABOFS≡≥	047602	004767	777004			JSR PC,TABOFS		;R0 ← offset into joint error table
≠ADD≡≡LTHPTR≡≡R0≡≥	047606	066700	744214			ADD LTHPTR,R0		;R0 ← LOC[proper place in joint ang table]
≠MOV≡≡R4≡≡R1≡≥	047612	010401				MOV R4,R1		;
≠ADD≡≡FMJOAN≡≡R1≡≥	047614	062701	000070			ADD #FMJOAN,R1		;R1 ← LOC[joint angle list in fmblock]
≠BIT≡≡AHAND≡≡FMMECH≡≡R4≡≥	047620	032764	000012	000120		BIT #AHAND,FMMECH(R4)	;Is it a hand?
≠BEQ≡≥	047626	001403				BEQ 3$			;No
≠MOV≡≡R3≡≥	047630	012703	000001			MOV #1,R3		;Yes, R3 ← 1 ← words to transfer
≠BR≡≥	047634	000402				BR  4$
≠MOV≡≡R3≡≥	047636	012703	000006		3$:	MOV #6,R3		;R3 ← 6 ← words to transfer
≠LDF≡≡R0≡≡AC0≡≥	047642	172430			4$:	LDF @(R0)+,AC0		;Transfer current joint angle
≠STF≡≡AC0≡≡R1≡≥	047644	174021				STF AC0,(R1)+		;
≠SOB≡≡R3≡≥	047646	077303				SOB  R3,4$		;repeat
≠MOV≡≡R4≡≡R0≡≥	047650	010400				MOV R4,R0		;
≠ADD≡≡FMFOMO≡≡R0≡≥	047652	062700	000000			ADD #FMFOMO,R0		;R0 ← LOC[force-moment array]
≠MOV≡≡R4≡≡R1≡≥	047656	010401				MOV R4,R1		;
≠ADD≡≡FMRETO≡≡R1≡≥	047660	062701	000040			ADD #FMRETO,R1		;R1 ← LOC[reaction torque array to be returned]
≠MOV≡≡FMMECH≡≡R4≡≡R3≡≥	047664	016403	000120			MOV FMMECH(R4),R3	;R3 ← mechanism number
≠MOV≡≡R4≡≡R2≡≥	047670	010402				MOV R4,R2		;
≠ADD≡≡FMJOAN≡≡R2≡≥	047672	062702	000070			ADD #FMJOAN,R2		;R2 ← LOC[current joint angles]
≠JSR≡≡PC≡≡LFORCE≡≥	047676	004777	744142			JSR PC,@LFORCE		;This actually fills the reaction torque array
≠MOV≡≡R4≡≡R0≡≥	047702	010400				MOV R4,R0		;
≠ADD≡≡FMRETO≡≡R0≡≥	047704	062700	000040			ADD #FMRETO,R0		;R0 ← LOC[reaction-torque array]
≠CLRF≡≡AC0≡≥	047710	170400				CLRF AC0		;AC0 ← sum of the squares
≠BIT≡≡AHAND≡≡FMMECH≡≡R4≡≥	047712	032764	000012	000120		BIT #AHAND,FMMECH(R4)	;Is it a hand?
≠BEQ≡≥	047720	001403				BEQ 5$			;No
≠MOV≡≡R3≡≥	047722	012703	000001			MOV #1,R3		;Yes, R3 ← 1 ← words to sum
≠BR≡≥	047726	000402				BR  6$
≠MOV≡≡R3≡≥	047730	012703	000006		5$:	MOV #6,R3		;R3 ← 6 ← words to sum
≠LDF≡≡R0≡≡AC1≡≥	047734	172510			6$:	LDF (R0),AC1		;compute sum of squares
≠MULF≡≡R0≡≡AC1≡≥	047736	171120				MULF (R0)+,AC1		;
≠ADDF≡≡AC1≡≡AC0≡≥	047740	172001				ADDF AC1,AC0		;
≠SOB≡≡R3≡≥	047742	077304				SOB R3,6$		;
≠STF≡≡AC0≡≡FMSCAL≡≡R4≡≥	047744	174064	000122			STF AC0,FMSCAL(R4)	;Store the sum of the squares
≤SLEEP≡≥						SLEEP #1000		;Sleep half a second
≤.ARG≡≥						  .ARG #1000
≠.LIF≡≥						    .LIF NB #1000
≠MOV≡≡SP≡≥	047750	012746	001000			      MOV #1000,-(SP)
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 182
	INTERP PAL[HAL,HE]	PAGE 24.3 	Table of interpreter instructions

≥	047754	104014				104014
≠BR≡≥	047756	000670				BR 1$			;Do it again
≠MOV≡≡R4≡≡R0≡≥	047760	010400			7$:	MOV R4,R0		;R0 ← LOC[fmblock]
≠JSR≡≡PC≡≡RLFREE≡≥	047762	004767	760622			JSR PC,RLFREE		;Release the fmblock
≠MOV≡≡SP≡≡R0≡≥	047766	012600			8$:	MOV (SP)+,R0		;R0 ← LOC[PCB]
≠JSR≡≡PC≡≡RLFREE≡≥	047770	004767	760614			JSR PC,RLFREE		;Release the PCB
≤DISMIS≡≥						DISMIS			;Go away.
≥	047774	104000				104000
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 183
	INTERP PAL[HAL,HE]	PAGE 25 	Table of interpreter instructions

≥					;Events:  MAKEVT, SIGNAL, WAITE, DESEVT, PAUSE
≥					
≠COMMEN≡≥				COMMENT ⊗ Events can be created (at the beginnings of blocks is the
≥				usual place), signaled, awaited (in the middle of a block) and
≥				destroyed (at the end of a block).  Each event is a variable, that
≥				is, it is refered to by a level-offset pair.  However, its place in
≥				the environment does not point to a graph node, since there is no
≥				such thing as attachment to an event.  The event itself is stored in
≥				the environment.  The garbage collector marking phase had better
≥					understand this.  ⊗
≥					
≥					MAKEVT:	;Interpreter routine
≥					
≠COMMEN≡≥				COMMENT ⊗ A list of arguments, each of which is an offset.  This list
≥				is terminated by a zero entry.  For each argument, a fresh event is
≥				created and placed in the environment at the desired offset, current
≥					level. ⊗
≥					
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	047776	017400	000000			MOV @IPC(R4),R0	;R0 ← offset
≠BIC≡≡R0≡≥	050002	042700	177400			BIC #177400,R0	;Get rid of level info.
≠BEQ≡≥	050006	001410				BEQ 1$		;If none, done
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	050010	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠ADD≡≡ENV≡≡R4≡≡R0≡≥	050016	066400	000006			ADD ENV(R4),R0	;R0 ← pointer into environment
≤EVMAK≡≥						EVMAK		;Make an event.
≥	050022	104004				104004
≠MOV≡≡SP≡≡R0≡≥	050024	012610				MOV (SP)+,(R0)	;Stuff it away.
≠BR≡≡MAKEVT≡≥	050026	000763				BR  MAKEVT	;Repeat
≤BMPIPC≡≥					1$:	BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	050030	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	050036	000207				RTS PC		;Done
≥					
≥					SIGNAL:	;Interpreter routine.  Signal the event of the level-offset pair.
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	050040	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset pair.
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	050044	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	050052	004767	766204			JSR PC,GETARG	;R0 ← equivalent pointer into environment
≤EVSIG≡≥						EVSIG (R0)	;Signal that event.
≤.ARG≡≥						  .ARG (R0)
≠.LIF≡≥						    .LIF NB (R0)
≠MOV≡≡R0≡≡SP≡≥	050056	011046				      MOV (R0),-(SP)
≥	050060	104012				104012
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	050062	000207				RTS PC		;Done
≥					
≥					WAITE:	;Interpreter routine.  Wait on the event of the level-offset pair.
≠MOV≡≡IPC≡≡R4≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 184
	INTERP PAL[HAL,HE]	PAGE 25.1 	Table of interpreter instructions

≥	050064	017400	000000			MOV @IPC(R4),R0	;R0 ← level-offset pair.
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	050070	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠JSR≡≡PC≡≡GETARG≡≥	050076	004767	766160			JSR PC,GETARG	;R0 ← equivalent pointer into environment
≤EVWAIT≡≥						EVWAIT (R0)	;Wait on that event.
≤.ARG≡≥						  .ARG (R0)
≠.LIF≡≥						    .LIF NB (R0)
≠MOV≡≡R0≡≡SP≡≥	050102	011046				      MOV (R0),-(SP)
≥	050104	104010				104010
≠BCC≡≥	050106	103002				BCC 1$		;Return OK?
≠JMP≡≡TERMIN≡≥	050110	000167	770652			JMP TERMINATE	;The event was destroyed.  I guess we should depart cleanly.
≠JSR≡≡PC≡≡NOTICE≡≥	050114	004767	775420		1$:	JSR PC,NOTICE	;Assume the world has gone awry.
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	050120	000207				RTS PC		;Done
≥					
≥					DESEVT:	;Interpreter routine
≥					
≠COMMEN≡≥				COMMENT ⊗ A list of arguments, each of which is an offset.  This list
≥				is terminated by a zero entry.  For each argument, the event is
≥					destroyed.  ⊗
≥					
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	050122	017400	000000			MOV @IPC(R4),R0	;Get offset
≠BIC≡≡R0≡≥	050126	042700	177400			BIC #177400,R0	;Remove level info.
≠BEQ≡≥	050132	001411				BEQ 1$		;If none, done
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	050134	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≠ADD≡≡ENV≡≡R4≡≡R0≡≥	050142	066400	000006			ADD ENV(R4),R0	;R0 ← pointer into environment
≤EVKIL≡≥						EVKIL (R0)	;Kill the event
≤.ARG≡≥						  .ARG (R0)
≠.LIF≡≥						    .LIF NB (R0)
≠MOV≡≡R0≡≡SP≡≥	050146	011046				      MOV (R0),-(SP)
≥	050150	104006				104006
≠CLR≡≡R0≡≥	050152	005010				CLR (R0)	;Remove the event from the environment
≠BR≡≡DESEVT≡≥	050154	000762				BR  DESEVT	;Repeat
≤BMPIPC≡≥					1$:	BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	050156	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤CCC≡≥						CCC		;Clear condition code.
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	050164	000207				RTS PC		;Done
≥					
≥					PAUSE:	;Interpreter routine
≠COMMEN≡≥					COMMENT ⊗ Pause n seconds, where n is on the stack.  ⊗
≠LDF≡≡R3≡≡AC0≡≥	050166	172433				LDF @(R3)+,AC0	;AC0 ← wait time
≠MULF≡≡THOUS≡≡AC0≡≥	050170	171067	000010			MULF THOUS,AC0	;AC0 ← time, in milliseconds
≠STCFI≡≡AC0≡≡R0≡≥	050174	175400				STCFI AC0,R0	;R0 ← time in milliseconds
≤SLEEP≡≥						SLEEP R0	;The pause that refreshes
≤.ARG≡≥						  .ARG R0
≠.LIF≡≥						    .LIF NB R0
≠MOV≡≡R0≡≡SP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 185
	INTERP PAL[HAL,HE]	PAGE 25.2 	Table of interpreter instructions

≥	050176	010046				      MOV R0,-(SP)
≥	050200	104014				104014
≤CCC≡≥						CCC		;Clear Condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	050202	000207				RTS PC		;Done
≥					
≠.WORD≡≥	050204	042572			THOUS:	.WORD 42572	;  1000.0
≠.WORD≡≥	050206	000000				.WORD 0		;
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 186
	INTERP PAL[HAL,HE]	PAGE 26 	Table of interpreter instructions

≥					;Output routines:  PRINT, VALPRN, VARPRN, TACKVAL, TYPVAL, CVFX
≥					
≥					PRINT:	;Interpreter routine
≠MOV≡≡IPC≡≡R4≡≡R0≡≥	050210	017400	000000			MOV @IPC(R4),R0	;R0 ← Address of string
≤BMPIPC≡≥						BMPIPC		;Bump IPC
≠ADD≡≡IPC≡≡R4≡≥	050214	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤EVWAIT≡≥						EVWAIT CSLEVT	;
≤.ARG≡≥						  .ARG CSLEVT
≠.LIF≡≥						    .LIF NB CSLEVT
≠MOV≡≡CSLEVT≡≡SP≡≥	050222	016746	744170			      MOV CSLEVT,-(SP)
≥	050226	104010				104010
≠JSR≡≡PC≡≡TYPSTR≡≥	050230	004767	743644			JSR PC,TYPSTR	;Type it out
≤EVSIG≡≥						EVSIG CSLEVT	;
≤.ARG≡≥						  .ARG CSLEVT
≠.LIF≡≥						    .LIF NB CSLEVT
≠MOV≡≡CSLEVT≡≡SP≡≥	050234	016746	744156			      MOV CSLEVT,-(SP)
≥	050240	104012				104012
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	050242	000207				RTS PC		;Done
≥					
≥					VARPRN:	
≠COMMEN≡≥				COMMENT ⊗ Interpreter routine.  Prints the graph node pointed to by
≥					the level-offset of the argument.  ⊗
≠JSR≡≡PC≡≡GTVAL≡≥	050244	004767	766360			JSR PC,GTVAL	;Let GTVAL put value on stack
≠JMP≡≡VALPRN≡≥	050250	000167	000000			JMP VALPRN	;And let VALPRN take it from there.
≥					
≥					VALPRN:	
≠COMMEN≡≥				COMMENT ⊗ Interpreter routine.  Prints the value the top of the stack
≥					and pops it.  ⊗
≠MOV≡≡R3≡≡R0≡≥	050254	012300				MOV (R3)+,R0	;R0 ← LOC[value cell]
≠JSR≡≡PC≡≡TYPVAL≡≥	050256	004767	000052			JSR PC,TYPVAL	;Go print it.
≤CCC≡≥						CCC		;Clear condition codes
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	050262	000207				RTS PC		;And return
≥					
≠.IFNZ≡≡ALAID≡≥		000001			.IFNZ ALAID
≥					
≥					TACKVAL:
≠COMMEN≡≥				COMMENT ⊗ R1 points to a value cell.  R0 points to a string where the
≥				value is to be placed.  Places it there just as TYPVAL prints it out,
≥					using common code.  ⊗
≠MOV≡≡R2≡≡SP≡≥	050264	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡R3≡≡SP≡≥	050266	010346				MOV R3,-(SP)	;Save R3
≠MOV≡≡TACKV≡≡SP≡≥	050270	012746	050312			MOV #TACKV,-(SP);Stack the address of the placing routine.
≠MOV≡≡R0≡≡R2≡≥	050274	010002				MOV R0,R2	;Exchange R0, R1
≠MOV≡≡R1≡≡R0≡≥	050276	010100				MOV R1,R0	;
≠MOV≡≡R2≡≡R1≡≥	050300	010201				MOV R2,R1	;Now R0 = value cell, R1 = string where to put it.
≠JSR≡≡PC≡≡TYPVL≡≥	050302	004767	000066			JSR PC,TYPVL	;And do just as TYPVAL does.
≠MOV≡≡R1≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 187
	INTERP PAL[HAL,HE]	PAGE 26.1 	Table of interpreter instructions

≥	050306	010100				MOV R1,R0	;Put back the final string pointer
≠BR≡≡TYPVRT≡≥	050310	000425				BR TYPVRT	;Return
≥					
≥					TACKV:	
≠COMMEN≡≥				COMMENT ⊗ R1 = string pointer, R0 = new addition.  Use TACK to put it
≥					on. ⊗
≠MOV≡≡R2≡≡SP≡≥	050312	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡R0≡≡R2≡≥	050314	010002				MOV R0,R2	;
≠MOV≡≡R1≡≡R0≡≥	050316	010100				MOV R1,R0	;
≠MOV≡≡R2≡≡R1≡≥	050320	010201				MOV R2,R1	;Now R0 = string poiter, R1 = new addition.
≠JSR≡≡PC≡≡TACK≡≥	050322	004767	005450			JSR PC,TACK	;
≠MOV≡≡R0≡≡R1≡≥	050326	010001				MOV R0,R1	;R1 = final string pointer.
≠MOV≡≡SP≡≡R2≡≥	050330	012602				MOV (SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	050332	000207				RTS PC		;Done
≥					.ENDC
≥					
≥					TYPVAL:
≠COMMEN≡≥				COMMENT ⊗ R0 points to a value cell.  Prints it according to its
≥					type.  Requires the floating package.  ⊗
≠MOV≡≡R2≡≡SP≡≥	050334	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡R3≡≡SP≡≥	050336	010346				MOV R3,-(SP)	;Save R3
≠MOV≡≡TYPSTR≡≡SP≡≥	050340	012746	014100			MOV #TYPSTR,-(SP)	;Stack the address of the typing routine.
≤EVWAIT≡≥						EVWAIT CSLEVT	;
≤.ARG≡≥						  .ARG CSLEVT
≠.LIF≡≥						    .LIF NB CSLEVT
≠MOV≡≡CSLEVT≡≡SP≡≥	050344	016746	744046			      MOV CSLEVT,-(SP)
≥	050350	104010				104010
≠JSR≡≡PC≡≡TYPVL≡≥	050352	004767	000016			JSR PC,TYPVL	;
≤EVSIG≡≥						EVSIG CSLEVT	;
≤.ARG≡≥						  .ARG CSLEVT
≠.LIF≡≥						    .LIF NB CSLEVT
≠MOV≡≡CSLEVT≡≡SP≡≥	050356	016746	744034			      MOV CSLEVT,-(SP)
≥	050362	104012				104012
≠TST≡≡SP≡≥	050364	005726			TYPVRT:	TST (SP)+	;Get rid of the address of typing routine.
≠MOV≡≡SP≡≡R3≡≥	050366	012603				MOV (SP)+,R3	;Restore R3
≠MOV≡≡SP≡≡R2≡≥	050370	012602				MOV (SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	050372	000207				RTS PC		;
≥					
≥						;R0 = LOC[value cell], R1 = LOC[string] in some cases.
≥						;R2, R3 are available for use.
≥					
≠MOV≡≡R0≡≡R2≡≥	050374	010002			TYPVL:	MOV R0,R2	;R2 ← LOC[value cell]
≠MOV≡≡CRLFX≡≡R0≡≥	050376	012700	014266			MOV #CRLFX,R0	;CRLF
≠JSR≡≡PC≡≡SP≡≥	050402	004776	000002			JSR PC,@2(SP)	;
≠CMPB≡≡SCLID≡≡TAGID≡≡R2≡≥	050406	122762	000001	777776		CMPB #SCLID,TAGID(R2)	;A scalar?
≠BEQ≡≥	050414	001410				BEQ 1$
≠CMPB≡≡VCTID≡≡TAGID≡≡R2≡≥	050416	122762	000002	777776		CMPB #VCTID,TAGID(R2)	;A vector?
≠BEQ≡≥	050424	001426				BEQ 4$
≠CMPB≡≡TRNID≡≡TAGID≡≡R2≡≥	050426	122762	000003	777776		CMPB #TRNID,TAGID(R2)	;A trans?
≠BEQ≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 188
	INTERP PAL[HAL,HE]	PAGE 26.2 	Table of interpreter instructions

≥	050434	001437				BEQ 5$
≠MOV≡≡SNAME≡≡R0≡≥	050436	012700	050730		1$:	MOV #SNAME,R0	;
≠JSR≡≡PC≡≡SP≡≥	050442	004776	000002			JSR PC,@2(SP)	;"SCALAR "
≠MOV≡≡OUTBUF≡≡R0≡≥	050446	012700	014762			MOV #OUTBUF,R0	;
≠LDF≡≡R2≡≡AC0≡≥	050452	172412			2$:	LDF (R2),AC0	;
≠JSR≡≡PC≡≡CVFX≡≥	050454	004767	000236			JSR PC,CVFX	;
≠MOV≡≡OUTBUF≡≡R0≡≥	050460	012700	014762			MOV #OUTBUF,R0	;
≠JSR≡≡PC≡≡SP≡≥	050464	004776	000002			JSR PC,@2(SP)	;
≠MOV≡≡CRLFX≡≡R0≡≥	050470	012700	014266		3$:	MOV #CRLFX,R0	;CRLF
≠JSR≡≡PC≡≡SP≡≥	050474	004776	000002			JSR PC,@2(SP)	;
≠RTS≡≡PC≡≥	050500	000207				RTS PC		;Done
≠MOV≡≡VNAME≡≡R0≡≥	050502	012700	050740		4$:	MOV #VNAME,R0	;
≠JSR≡≡PC≡≡SP≡≥	050506	004776	000002			JSR PC,@2(SP)	;"VECTOR "
≠MOV≡≡OUTBUF≡≡R0≡≥	050512	012700	014762			MOV #OUTBUF,R0	;
≠LDF≡≡R2≡≡AC0≡≥	050516	172422				LDF (R2)+,AC0	;
≠JSR≡≡PC≡≡CVFX≡≥	050520	004767	000172			JSR PC,CVFX	;
≠LDF≡≡R2≡≡AC0≡≥	050524	172422				LDF (R2)+,AC0	;
≠JSR≡≡PC≡≡CVFX≡≥	050526	004767	000164			JSR PC,CVFX	;
≠BR≡≥	050532	000747				BR  2$		;Bum code for last field.
≠MOV≡≡TNAME≡≡R0≡≥	050534	012700	050750		5$:	MOV #TNAME,R0	;
≠JSR≡≡PC≡≡SP≡≥	050540	004776	000002			JSR PC,@2(SP)	;"TRANS "
≠MOV≡≡R3≡≡SP≡≥	050544	010346				MOV R3,-(SP)	;Save R3
≠MOV≡≡R3≡≥	050546	012703	000003			MOV #3,R3	;R3 ← Number of rows
≠MOV≡≡CRLFX≡≡R0≡≥	050552	012700	014266		6$:	MOV #CRLFX,R0	;
≠JSR≡≡PC≡≡SP≡≥	050556	004776	000004			JSR PC,@4(SP)	;
≠MOV≡≡OUTBUF≡≡R0≡≥	050562	012700	014762			MOV #OUTBUF,R0	;
≠LDF≡≡R2≡≡AC0≡≥	050566	172412				LDF (R2),AC0	;
≠JSR≡≡PC≡≡CVFX≡≥	050570	004767	000122			JSR PC,CVFX	;
≠LDF≡≡R2≡≡AC0≡≥	050574	172462	000014			LDF 14(R2),AC0	;
≠JSR≡≡PC≡≡CVFX≡≥	050600	004767	000112			JSR PC,CVFX	;
≠LDF≡≡R2≡≡AC0≡≥	050604	172462	000030			LDF 30(R2),AC0	;
≠JSR≡≡PC≡≡CVFX≡≥	050610	004767	000102			JSR PC,CVFX	;
≠LDF≡≡R2≡≡AC0≡≥	050614	172462	000044			LDF 44(R2),AC0	;
≠JSR≡≡PC≡≡CVFX≡≥	050620	004767	000072			JSR PC,CVFX	;
≠MOV≡≡OUTBUF≡≡R0≡≥	050624	012700	014762			MOV #OUTBUF,R0	;
≠JSR≡≡PC≡≡SP≡≥	050630	004776	000004			JSR PC,@4(SP)	;
≠ADD≡≡R2≡≥	050634	062702	000004			ADD #4,R2	;Next row
≠SOB≡≡R3≡≥	050640	077334				SOB R3,6$	;
≠MOV≡≡CRLFX≡≡R0≡≥	050642	012700	014266			MOV #CRLFX,R0	;
≠JSR≡≡PC≡≡SP≡≥	050646	004776	000004			JSR PC,@4(SP)	;
≠MOV≡≡OUTBUF≡≡R0≡≥	050652	012700	014762			MOV #OUTBUF,R0	;
≠MOV≡≡R3≡≥	050656	012703	000003			MOV #3,R3	;Now do the 0 0 0 1 row
≠CLRF≡≡AC0≡≥	050662	170400			7$:	CLRF AC0
≠JSR≡≡PC≡≡CVFX≡≥	050664	004767	000026			JSR PC,CVFX	;
≠SOB≡≡R3≡≥	050670	077304				SOB R3,7$
≠LDF≡≡ONE≡≡AC0≡≥	050672	172467	000434			LDF ONE,AC0
≠JSR≡≡PC≡≡CVFX≡≥	050676	004767	000014			JSR PC,CVFX
≠MOV≡≡OUTBUF≡≡R0≡≥	050702	012700	014762			MOV #OUTBUF,R0	;
≠JSR≡≡PC≡≡SP≡≥	050706	004776	000004			JSR PC,@4(SP)	;
≠MOV≡≡SP≡≡R3≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 189
	INTERP PAL[HAL,HE]	PAGE 26.3 	Table of interpreter instructions

≥	050712	012603				MOV (SP)+,R3	;Restore R3
≠BR≡≥	050714	000665				BR  3$		;Go to the exit stage
≥					
≥					CVFX:	;Version of CVF that saves R1.
≠MOV≡≡R1≡≡SP≡≥	050716	010146				MOV R1,-(SP)	;
≠JSR≡≡PC≡≡CVF≡≥	050720	004767	001110			JSR PC,CVF	;
≠MOV≡≡SP≡≡R1≡≥	050724	012601				MOV (SP)+,R1	;
≠RTS≡≡PC≡≥	050726	000207				RTS PC		;
≥					
≤ASCIE≡≥					SNAME:	ASCIE /SCALAR /
≠.ASCIZ≡≥	050730	   123		
≥	050731	   103		
≥	050732	   101		
≥	050733	   114		
≥	050734	   101		
≥	050735	   122		
≥	050736	   040		
≥	050737	   000		
≥					       .ASCIZ /SCALAR /
≠.EVEN≡≥		050740			       .EVEN
≤ASCIE≡≥					VNAME:	ASCIE /VECTOR /
≠.ASCIZ≡≥	050740	   126		
≥	050741	   105		
≥	050742	   103		
≥	050743	   124		
≥	050744	   117		
≥	050745	   122		
≥	050746	   040		
≥	050747	   000		
≥					       .ASCIZ /VECTOR /
≠.EVEN≡≥		050750			       .EVEN
≤ASCIE≡≥					TNAME:	ASCIE /TRANS /
≠.ASCIZ≡≥	050750	   124		
≥	050751	   122		
≥	050752	   101		
≥	050753	   116		
≥	050754	   123		
≥	050755	   040		
≥	050756	   000		
≥					       .ASCIZ /TRANS /
≠.EVEN≡≥		050760			       .EVEN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 190
	INTERP PAL[HAL,HE]	PAGE 27 	Table of interpreter instructions

≥					;  BREAK, NOOP, TOPAL
≥					
≠.IFZ≡≡ALAID≡≥		000001			    .IFZ ALAID
≥					BREAK:	;Interpreter routine
≥						MOV #BRKMES,R0	;
≥						JSR PC,TYPSTR	;
≥						BPT		;Cause a DDT break
≥						CCC		;Clear condition code
≥						RTS PC		;Done
≥					BRKMES:	ASCIE </
≥					PROGRAM BREAK/>
≥					    .ENDC
≥					
≥					NOOP:	;Interpreter routine
≤CCC≡≥						CCC		;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	050760	000207				RTS PC		;Done
≥					
≥					TOPAL:	;Interpreter routine
≠COMMEN≡≥				        COMMENT ⊗ Escape to PAL.  JSRs to the pseudo code.  That code
≥				        should return via: 
≥				            MOV PC,R0
≥				            RTS PC
≥						⊗
≠JSR≡≡PC≡≡IPC≡≡R4≡≥	050762	004774	000000			JSR PC,@IPC(R4)	;Fly
≠ADD≡≡R0≡≥	050766	062700	000002			ADD #2,R0	;R0 ← Proper new IPC
≠MOV≡≡R0≡≡IPC≡≡R4≡≥	050772	010064	000000			MOV R0,IPC(R4)	;Hope R4, R3 still OK!
≠RTS≡≡PC≡≥	050776	000207				RTS PC		;Done.
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 191
	INTERP PAL[HAL,HE]	PAGE 28 	Table of interpreter instructions

≥					;Initialization psops:  PROG, ENDP, FIXIT
≥					
≥					PROG:
≠COMMEN≡≥				COMMENT ⊗  Sets up the variables for each arm, with the associated
≥				calculators.  This is done by using some special-purpose pseudo-code
≥				and setting this interpreter to work on it.  There is one argument,
≥					which is the version number of the pcode. ⊗
≠MOV≡≡IPC≡≡R4≡≡SP≡≥	051000	016446	000000			MOV IPC(R4),-(SP)	;Save the IPC.
≠MOV≡≡PROGCD≡≡IPC≡≡R4≡≥	051004	012764	051034	000000		MOV #PROGCD,IPC(R4)	;Set up a funny IPC
≤CALL≡≥						CALL INTERP		;Call ourselves to execute the code.
≠MOV≡≡RF≡≡SP≡≥	051012	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB 
≥						       .IRP II,<>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	051014	012746	006400			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	051020	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡INTERP≡≥	051022	004767	764770			JSR	PC,INTERP		;Call the routine
≠MOV≡≡SP≡≡IPC≡≡R4≡≥	051026	012664	000000			MOV (SP)+,IPC(R4)	;Restore the IPC
≤CCC≡≥						CCC			;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	051032	000207				RTS PC			;Done
≥					
≥					PROGCD:	
≡XMVAR≡≡XMVAR≡≥	051034	000012				XMVAR			;Make the mechanism variables
≠.IFNZ≡≡YELLOW≡≥		000000			    .IFNZ YELLOW
≥						YAOFST
≥						YHOFST
≥					    .ENDC
≡BAOFST≡≡BAOFST≡≥	051036	000014				BAOFST
≡BHOFST≡≡BHOFST≡≥	051040	000016				BHOFST
≡BDEPRO≡≡BDEPRO≡≥	051042	000030				BDEPROACH		;Make the deproach variables
≡YDEPRO≡≡YDEPRO≡≥	051044	000032				YDEPROACH
≥	051046	000000				0
≠.IFNZ≡≡YELLOW≡≥		000000			    .IFNZ YELLOW
≥						XMEXP			;The expression for updating the YARM
≥						0			;  no neededs (so not dependent on the mechanism)
≥						PCDYA			;  code
≥						YACOFS			;  offset of expression
≥						XMCLC			;Make it a calculator
≥						YACOFS			;  offset of expression
≥						YAOFST			;  offset of variable
≥					
≥						XMEXP			;The expression for updating the YHAND
≥						0			;  no neededs (so not dependent on the mechanism)
≥						PCDYH			;  code
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 192
	INTERP PAL[HAL,HE]	PAGE 28.1 	Table of interpreter instructions

≥						YHCOFS			;  offset of expression
≥						XMCLC			;Make it a calculator
≥						YHCOFS			;  offset of expression
≥						YHOFST			;  offset of variable
≥					    .ENDC
≥					
≡XMEXP≡≡XMEXP≡≥	051050	000024				XMEXP			;The expression for updating the BARM
≥	051052	000000				0			;  no neededs (so not dependent on the mechanism)
≡PCDBA≡≡PCDBA≡≥	051054	051112				PCDBA			;  code
≡BACOFS≡≡BACOFS≡≥	051056	000010				BACOFS			;  offset of expression
≡XMCLC≡≡XMCLC≡≥	051060	000026				XMCLC			;Make it a calculator
≡BACOFS≡≡BACOFS≡≥	051062	000010				BACOFS			;  offset of expression
≡BAOFST≡≡BAOFST≡≥	051064	000014				BAOFST			;  offset of variable
≥					
≡XMEXP≡≡XMEXP≡≥	051066	000024				XMEXP			;The expression for updating the BHAND
≥	051070	000000				0			;  no neededs (so not dependent on the mechanism)
≡PCDBH≡≡PCDBH≡≥	051072	051120				PCDBH			;  code
≡BHCOFS≡≡BHCOFS≡≥	051074	000012				BHCOFS			;  offset of expression
≡XMCLC≡≡XMCLC≡≥	051076	000026				XMCLC			;Make it a calculator
≡BHCOFS≡≡BHCOFS≡≥	051100	000012				BHCOFS			;  offset of expression
≡BHOFST≡≡BHOFST≡≥	051102	000016				BHOFST			;  offset of variable
≡XPUSH≡≡XPUSH≡≥	051104	000050				XPUSH			;Put some junk on the stack
≥	051106	000000				0			;
≡XENDCL≡≡XENDCL≡≥	051110	000070				XENDCLC			;Returns to caller, and clears the stack
≥					
≠.IFNZ≡≡YELLOW≡≥		000000			    .IFNZ YELLOW
≥					;PCDYA:	XWHERE			;Expression for YARM
≥						YARM			;
≥						XENDCLC			;
≥					;PCDYH:	XWHERE			;Expression for YHAND
≥						YHAND			;
≥						XENDCLC			;
≥					    .ENDC
≡XWHERE≡≡XWHERE≡≥	051112	000136			PCDBA:	XWHERE			;Expression for BARM
≡BARM≡≡BARM≡≥	051114	000004				BARM			;
≡XENDCL≡≡XENDCL≡≥	051116	000070				XENDCLC			;
≡XWHERE≡≡XWHERE≡≥	051120	000136			PCDBH:	XWHERE			;Expression for BHAND
≡BHAND≡≡BHAND≡≥	051122	000010				BHAND			;
≡XENDCL≡≡XENDCL≡≥	051124	000070				XENDCLC			;
≥					
≥					ENDP:
≠COMMEN≡≥				COMMENT ⊗  Cleans up the variables for each arm, with the associated
≥				calculators.  This is done by using some special-purpose pseudo-code
≥					and setting this interpreter to work on it.  ⊗
≠MOV≡≡IPC≡≡R4≡≡SP≡≥	051126	016446	000000			MOV IPC(R4),-(SP)	;Save the IPC.
≠MOV≡≡ENDPCD≡≡IPC≡≡R4≡≥	051132	012764	051164	000000		MOV #ENDPCD,IPC(R4)	;Set up a funny IPC
≤CALL≡≥						CALL INTERP		;Call ourselves to execute the code.
≠MOV≡≡RF≡≡SP≡≥	051140	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 193
	INTERP PAL[HAL,HE]	PAGE 28.2 	Table of interpreter instructions

≥						   .IFNB 
≥						       .IRP II,<>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	051142	012746	006400			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	051146	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡INTERP≡≥	051150	004767	764642			JSR	PC,INTERP		;Call the routine
≠MOV≡≡SP≡≡IPC≡≡R4≡≥	051154	012664	000000			MOV (SP)+,IPC(R4)	;Restore the IPC
≤CCC≡≥						CCC			;Clear condition code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠JMP≡≡TERMIN≡≥	051160	000167	767602			JMP TERMINATE		;Done with the interpreter
≥					
≥					ENDPCD:
≡XKVAR≡≡XKVAR≡≥	051164	000014				XKVAR			;Kill the mechanism variables
≠.IFNZ≡≡YELLOW≡≥		000000			    .IFNZ YELLOW
≥						YAOFST
≥						YHOFST
≥					    .ENDC
≡BAOFST≡≡BAOFST≡≥	051166	000014				BAOFST
≡BHOFST≡≡BHOFST≡≥	051170	000016				BHOFST
≡BDEPRO≡≡BDEPRO≡≥	051172	000030				BDEPROACH		;Kill the deproach variables
≡YDEPRO≡≡YDEPRO≡≥	051174	000032				YDEPROACH
≥	051176	000000				0
≡XPUSH≡≡XPUSH≡≥	051200	000050				XPUSH			;Put some junk on the stack
≥	051202	000000				0			;
≡XENDCL≡≡XENDCL≡≥	051204	000070				XENDCLC			;Returns to caller, and clears the stack
≥					
≥					FIXIT:	
≠COMMEN≡≥				COMMENT ⊗ This should only have to be called from DDT.  Unwedges the
≥					servos.  ⊗
≠MOV≡≡R0≡≥	051206	012700	000034			MOV #34,R0		;
≠JSR≡≡PC≡≡GTFREE≡≥	051212	004767	757030			JSR PC,GTFREE		;Get a device block
≠MOV≡≡R0≡≡SP≡≥	051216	010046				MOV R0,-(SP)		;
≠MOV≡≡R0≡≡R1≡≥	051220	010001				MOV R0,R1		;
≠JSR≡≡PC≡≡LINTAR≡≥	051222	004777	742566			JSR PC,@LINTARM		;Initialize all servos
≠TST≡≡R0≡≥	051226	005700				TST R0			;All well?
≠BEQ≡≥	051230	001410				BEQ 1$			;Yes
≠MOV≡≡R0≡≡SP≡≥	051232	010046				MOV R0,-(SP)		;No
≠MOV≡≡FIXM≡≡R0≡≥	051234	012700	051262			MOV #FIXM,R0		;Complain.
≠JSR≡≡PC≡≡TYPSTR≡≥	051240	004767	742634			JSR PC,TYPSTR		;   without getting back into DDT prematurely
≠MOV≡≡SP≡≡R0≡≥	051244	012600				MOV (SP)+,R0		;
≠JSR≡≡PC≡≡TYPOCT≡≥	051246	004767	742656			JSR PC,TYPOCT		;
≠MOV≡≡SP≡≡R0≡≥	051252	012600			1$:	MOV (SP)+,R0		;
≠JSR≡≡PC≡≡RLFREE≡≥	051254	004767	757330			JSR PC,RLFREE		;Reclaim the device block
≠RTS≡≡PC≡≥	051260	000207				RTS PC			;
≤ASCIE≡≥				FIXM:	ASCIE </
≥					CAN'T INITIALIZE ARM.  ERROR CODE = />
≠.ASCIZ≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 194
	INTERP PAL[HAL,HE]	PAGE 28.3 	Table of interpreter instructions

≥	051262	   015		
≥	051263	   012			       .ASCIZ /
≥	051264	   103		
≥	051265	   101		
≥	051266	   116		
≥	051267	   047		
≥	051270	   124		
≥	051271	   040		
≥	051272	   111		
≥	051273	   116		
≥	051274	   111		
≥	051275	   124		
≥	051276	   111		
≥	051277	   101		
≥	051300	   114		
≥	051301	   111		
≥	051302	   132		
≥	051303	   105		
≥	051304	   040		
≥	051305	   101		
≥	051306	   122		
≥	051307	   115		
≥	051310	   056		
≥	051311	   040		
≥	051312	   040		
≥	051313	   105		
≥	051314	   122		
≥	051315	   122		
≥	051316	   117		
≥	051317	   122		
≥	051320	   040		
≥	051321	   103		
≥	051322	   117		
≥	051323	   104		
≥	051324	   105		
≥	051325	   040		
≥	051326	   075		
≥	051327	   040		
≥	051330	   000		
≥					CAN'T INITIALIZE ARM.  ERROR CODE = /
≠.EVEN≡≥		051332			       .EVEN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 195
	INTERP PAL[HAL,HE]	PAGE 29 	Table of interpreter instructions

≥					;BUGS
≥					
≠COMMEN≡≥				COMMENT ⊗
≥				Any variables (like FORCE variables, CMONS, or ordinary declared
≥				variables) inside the conclusion of a CMON use level-offsets later
≥				used for other things.  Fix: Let the conclusion of a CMON be at a new
≥				lexical level.  Changes to PASS3: Trivial.  Changes to INTERP: Make
≥				CMTRIG do the nasty work. (DONE changes made to PASS3 & CMMAK - ARG 11/76)
≥					⊗
≠.IFZ≡≡MOVING≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 196
	HAL PAL[HAL,HE]	PAGE 2.4 	Table of interpreter instructions

≥		000001			    .IFZ MOVING
≥					        .INSRT ARITH.PAL[HAL,HE]
≥					        PUTLOC LSQRTF,SQRTF     ;Global declaration
≥					        PUTLOC LSNCSD,SNCOS     ;Global declaration
≥					        PUTLOC LACOS,ACOS	;Global declaration
≥					    .IFF
≠.WORD≡≥	051332	040200		
≥	051334	000000				ONE: .WORD 40200,0	;1.0
≥					    .ENDC
≥					.ENDC
≥					
≠.IFNZ≡≡FLOAT≡≥		000001			.IFNZ FLOAT		;The floating I/O
≠.INSRT≡≥					    .INSRT FLOAT.PAL[HAL,HE]
≠COMMEN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 197
	FLOAT PAL[HAL,HE]	PAGE 1 	Table of interpreter instructions

≥				COMMENT ⊗   VALID 00012 PAGES
≥				C REC  PAGE   DESCRIPTION
≥				C00001 00001
≥				C00003 00002	.SBTTL  Floating point routines
≥				C00004 00003	STRING TO FLOATING POINT NUMBER ROUTINE - "RELSCN".
≥				C00007 00004		[CONTINUATION OF "RELSCN"]
≥				C00010 00005		[CONTINUATION OF "RELSCN"]
≥				C00012 00006	ROUTINES TO SET AND RESTORE OUTPUT FORMAT - "FORMAT"&"RSTFOR"
≥				C00014 00007	FLOATING POINT NUMBER TO "F" FORMAT STRING ROUTINE - "CVF"
≥				C00017 00008	FLOATING POINT NUMBER TO "E" FORMAT STRING ROUTINE - "CVE"
≥				C00020 00009		[CONTINUATION OF "CVE"]
≥				C00021 00010	FLOATING POINT NUMBER TO "E" OR "F" FORMAT STRING  - "CVG"
≥				C00023 00011		PRINTING ROUTINE USED BY "CVF" & "CVE"
≥				C00026 00012	LOCAL STORAGE AREA
≥				C00031 ENDMK
≥					C⊗;
≠.SBTTL≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 198
	FLOAT PAL[HAL,HE]	PAGE 2 	Floating point routines

≥					.SBTTL  Floating point routines
≥					
≥					;The following pages contain floating point input-output routines.
≥					;Coded by BES 9/74.
≥					
≥					
≠.IFNZ≡≡FLOAT≡≥		000001			.IFNZ FLOAT
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 199
	FLOAT PAL[HAL,HE]	PAGE 3 	Floating point routines

≥					;STRING TO FLOATING POINT NUMBER ROUTINE - "RELSCN".
≥					
≥					;THE FLOATING POINT NUMBER MUST BE OF THE FORM SIII.DDDESXX WHERE S IS
≥					;THE SIGN OF THE NUMBER, III IS THE INTEGER FIELD,  DDD IS THE DECIMAL
≥					;FIELD,  AND SXX  IS THE EXPONENT  AND ITS SIGN.   THE LENGTH OF  EACH
≥					;FIELD IS VARIABLE  BUT ONLY THE FIRST 8 DIGITS  ARE USED IN COMPUTING
≥					;THE F.P.   NUMBER.  EMPTY FIELDS ARE PERMITTED AND ALL LEADING SPACES
≥					;AND ZEROS ARE IGNORED.  THE LOCATION OF THE FIRST  BYTE OF THE STRING
≥					;MUST  BE LOADED INTO  R0 BEFORE  CALLING "RELSCN".   AFTER EXECUTION,
≥					;THIS ROUTINE LEAVES THE F.P. NUMBER IN REGISTER AC0 AND R0 POINTS  TO
≥					;THE BYTE FOLLOWING THE LAST DIGIT.  R1 CONTAINS AN ERROR CODE.  IF NO
≥					;NUMBER WAS FOUND, R1 IS  -1 ELSE R1 IS 0.  "RELSCN" IS  CALLED IN THE
≥					;"SIMPLE STYLE".
≥					
≥					;REGISTERS USED:
≥					;
≥					;	R0,R1,AC0 PASS ARGUMENTS
≥					;	NO OTHER REGISTERS AFFECTED
≥					
≠.STITL≡≥					.STITLE FLOATING POINT TO/FROM STRING CONVERSION ROUTINES
≥					
≥					;"DIGIT" CHECKS FOR ASC DIGIT AND CONVERTS TO INTEGER IF IT IS
≥					
≠.MACRO≡≤DIGIT≠≥					.MACRO DIGIT NOTDIG
≥						CMP	R4,#60		;COMPARE TO ASC ZERO
≥						BLT	NOTDIG		;SKIP IF OUT OF RANGE
≥						CMP	R4,#71		;COMPARE TO ASC 9
≥						BGT	NOTDIG		;SKIP IF OUT OF RANGE
≥						BIC	#60,R4		;MASK OUT ASC BASE
≥					.ENDM
≥					
≥					;"CKSIGN" CHECKS FOR A - OR + CHARACTER AND SETS SIGN APPROPRIATELY
≥					
≠.MACRO≡≤CKSIGN≠≥					.MACRO CKSIGN ISSIGN,NTSIGN,SIGN
≥						CMP	#53,R4		;IGNOR "+" CHARACTER
≥						BEQ	ISSIGN
≥						CMP	#55,R4		;CHECK IF ITS A "-" CHAR.
≥						BNE	NTSIGN		;EXIT IF ITS NOT
≥						INC	SIGN		;ELSE SET SIGN NON-ZERO
≥						BR 	ISSIGN
≥					.ENDM
≥					
≥					;START OF "RELSCN"
≥					
≠.EVEN≡≥		051336			.EVEN
≠MOV≡≡R2≡≡SP≡≥	051336	010246			RELSCN:	MOV	R2,-(SP)	;SAVE REGISTER
≠MOV≡≡R3≡≡SP≡≥	051340	010346			      	MOV	R3,-(SP)	;SAVE REGISTER
≠MOV≡≡R4≡≡SP≡≥	051342	010446				MOV	R4,-(SP)
≠CLR≡≡R2≡≥	051344	005002			      	CLR	R2 		;RESET DIGIT COUNT
≠MOV≡≡R3≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 200
	FLOAT PAL[HAL,HE]	PAGE 3.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	051346	012703	000001			MOV	#1,R3		;SET DECIMAL POINT FLAG
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 201
	FLOAT PAL[HAL,HE]	PAGE 4 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥						[CONTINUATION OF "RELSCN"]
≥					
≠MOV≡≡R1≡≥	051352	012701	777777			MOV	#-1,R1		;INDICATE NO DIGITS ENCOUNTERED
≠CLRF≡≡AC0≡≥	051356	170400			 	CLRF	AC0		;CLEAR THE NUMBER ACCUM
≠CLR≡≡MSIGN≡≥	051360	005067	001254			CLR	MSIGN		;ASSUME MANTISSA POSITIVE
≥					
≥					;PICK UP A CHARACTER AND CHECK FOR SIGN
≥					
≠MOVB≡≡R0≡≡R4≡≥	051364	112004			PICK:	MOVB	(R0)+,R4	;PICK UP A CHARACTER
≠TST≡≡R1≡≥	051366	005701				TST	R1		;CHECK IF DIGIT ENCOUNTERED
≠BEQ≡≡CHKDG≡≥	051370	001411				BEQ	CHKDG		;SKIP IF TRUE
≤CKSIGN≡≥						CKSIGN	PICK,CHKDG,MSIGN	;CHECK FOR + OR - SIGN
≠CMP≡≡R4≡≥	051372	022704	000053			CMP	#53,R4		;IGNOR "+" CHARACTER
≠BEQ≡≡PICK≡≥	051376	001772				BEQ	PICK
≠CMP≡≡R4≡≥	051400	022704	000055			CMP	#55,R4		;CHECK IF ITS A "-" CHAR.
≠BNE≡≡CHKDG≡≥	051404	001003				BNE	CHKDG		;EXIT IF ITS NOT
≠INC≡≡MSIGN≡≥	051406	005267	001226			INC	MSIGN		;ELSE SET MSIGN NON-ZERO
≠BR≡≡PICK≡≥	051412	000764				BR 	PICK
≥					
≥					;CHECK IF CHARARCTER IS A DIGIT
≥					
≤DIGIT≡≥					CHKDG:	DIGIT	CHKDP		;SKIP TO CHKDP IF NOT A DIGIT
≠CMP≡≡R4≡≥	051414	020427	000060			CMP	R4,#60		;COMPARE TO ASC ZERO
≠BLT≡≡CHKDP≡≥	051420	002420				BLT	CHKDP		;SKIP IF OUT OF RANGE
≠CMP≡≡R4≡≥	051422	020427	000071			CMP	R4,#71		;COMPARE TO ASC 9
≠BGT≡≡CHKDP≡≥	051426	003015				BGT	CHKDP		;SKIP IF OUT OF RANGE
≠BIC≡≡R4≡≥	051430	042704	000060			BIC	#60,R4		;MASK OUT ASC BASE
≠MULF≡≡TEN≡≡AC0≡≥	051434	171067	001530			MULF	TEN,AC0		;MULT DIGIT SUM BY 10
≠ASH≡≡R4≡≥	051440	072427	000002			ASH	#2,R4		;MULTIPLY INDEX BY 4
≠ADDF≡≡DGLST≡≡R4≡≡AC0≡≥	051444	172064	052664			ADDF	DGLST(R4),AC0	;ADD THE F.P. TO ACCUM
≠CLR≡≡R1≡≥	051450	005001				CLR     R1    		;INDICATE DIGIT ENCOUNTERED
≠SUB≡≡R2≡≥	051452	162702	000004			SUB     #4,R2		;DECREMENT DIGIT COUNT
≠JMP≡≡PICK≡≥	051456	000167	777702			JMP	PICK		;GO GET ANOTHER CHARACTER
≥					
≥					;CHECK IF THE CHARACTER IS A DECIMAL POINT
≥					
≠CMP≡≡R4≡≥	051462	022704	000056		CHKDP:	CMP	#56,R4		;COMPARE CHARACTER TO DECIMAL PT
≠BNE≡≡RNORM≡≥	051466	001007				BNE	RNORM		;SKIP IF NOT D.P.
≠TST≡≡R3≡≥	051470	005703			      	TST	R3		;CHECK IF DECIMAL POINT ALREADY SET
≠BEQ≡≡RNORM≡≥	051472	001405				BEQ	RNORM		;IF RESET THIS MUST BE A THE END OF THE MANT.
≠CLR≡≡R2≡≥	051474	005002				CLR	R2		;START COUNTING FRACTIONAL DIGITS
≠CLR≡≡R3≡≥	051476	005003				CLR	R3		;INDICATE D.P. SET
≠CLR≡≡R1≡≥	051500	005001				CLR	R1		;INDICATE DIGIT ENCOUNTERED
≠JMP≡≡PICK≡≥	051502	000167	777656			JMP	PICK		;GO GET ANOTHER CHARACTER
≥					
≥					;CORRECT NUMBER FOR POWER OF TEN IF DIGITS FOUND
≥					
≠TST≡≡R1≡≥	051506	005701			RNORM:	TST	R1		;CHECK IF DIGITS FOUND
≠BNE≡≡CHKEX≡≥	051510	001004				BNE	CHKEX		;SKIP IF NONE
≠TST≡≡R3≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 202
	FLOAT PAL[HAL,HE]	PAGE 4.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	051512	005703				TST	R3		;CHECK IF DECIMAL POINT SET
≠BNE≡≡CHKEX≡≥	051514	001002				BNE	CHKEX		;DONT NORMALIZE IF NO D.P.
≠MULF≡≡TENLST≡≡R2≡≡AC0≡≥	051516	171062	053164		    	MULF	TENLST(R2),AC0	;CORRECT DECIMAL POINT
≥					
≥					;CHECK IF E SIGN ENCOUNTERED
≥					
≠CMP≡≡R4≡≥	051522	022704	000105		CHKEX:	CMP	#105,R4		;COMPARE TO E CHARACTER
≠BNE≡≡CHKDN≡≥	051526	001052				BNE	CHKDN		;SKIP IF NOT E
≠TST≡≡R1≡≥	051530	005701				TST	R1   		;CHECK IF NO DIGITS BEFORE E
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 203
	FLOAT PAL[HAL,HE]	PAGE 5 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥						[CONTINUATION OF "RELSCN"]
≥					
≠BEQ≡≡EXCN≡≥	051532	001403				BEQ	EXCN
≠LDF≡≡TENLST≡≡AC0≡≥	051534	172467	001424			LDF	TENLST,AC0	;SET AC0=1 IF EXPONENT BUT NO DIGITS
≠CLR≡≡R1≡≥	051540	005001				CLR	R1		;INDICATE DIGITS ENCOUNTERED
≠CLR≡≡ESIGN≡≥	051542	005067	001074		EXCN:	CLR	ESIGN		;ASSUME EXPONENT POSITIVE
≠CLR≡≡R3≡≥	051546	005003				CLR	R3		;CLEAR EXPONENT ACCUMULATOR
≥					
≠MOVB≡≡R0≡≡R4≡≥	051550	112004				MOVB	(R0)+,R4	;GET NEXT CHARACTER
≤CKSIGN≡≥						CKSIGN	PIC2,DIG2,ESIGN	;CHECK FOR SIGN CHARACTER
≠CMP≡≡R4≡≥	051552	022704	000053			CMP	#53,R4		;IGNOR "+" CHARACTER
≠BEQ≡≡PIC2≡≥	051556	001406				BEQ	PIC2
≠CMP≡≡R4≡≥	051560	022704	000055			CMP	#55,R4		;CHECK IF ITS A "-" CHAR.
≠BNE≡≡DIG2≡≥	051564	001004				BNE	DIG2		;EXIT IF ITS NOT
≠INC≡≡ESIGN≡≥	051566	005267	001050			INC	ESIGN		;ELSE SET ESIGN NON-ZERO
≠BR≡≡PIC2≡≥	051572	000400				BR 	PIC2
≠MOVB≡≡R0≡≡R4≡≥	051574	112004			PIC2:	MOVB	(R0)+,R4	;SIGN INCOUNTERED, GET NEXT CHAR.
≤DIGIT≡≥					DIG2:	DIGIT	NORM		;EXTRACT DIGIT 
≠CMP≡≡R4≡≥	051576	020427	000060			CMP	R4,#60		;COMPARE TO ASC ZERO
≠BLT≡≡NORM≡≥	051602	002412				BLT	NORM		;SKIP IF OUT OF RANGE
≠CMP≡≡R4≡≥	051604	020427	000071			CMP	R4,#71		;COMPARE TO ASC 9
≠BGT≡≡NORM≡≥	051610	003007				BGT	NORM		;SKIP IF OUT OF RANGE
≠BIC≡≡R4≡≥	051612	042704	000060			BIC	#60,R4		;MASK OUT ASC BASE
≠MUL≡≡R3≡≥	051616	070327	000012			MUL	#10.,R3		;MULT EXPON REG BY 10.
≠ADD≡≡R4≡≡R3≡≥	051622	060403				ADD	R4,R3		;ADD DIGIT TO EXPONENT REG
≠JMP≡≡PIC2≡≥	051624	000167	777744			JMP	PIC2		;GO GET ANOTHER CHARACTER
≥					
≠TST≡≡ESIGN≡≥	051630	005767	001006		NORM:	TST	ESIGN		;CHECK SIGN OF EXPONENT
≠BEQ≡≥	051634	001401				BEQ	.+4
≠NEG≡≡R3≡≥	051636	005403				NEG	R3		;COMPLEMENT EXPONENT IF - SIGN
≠ASH≡≡R3≡≥	051640	072327	000002			ASH	#2,R3		;MULT. INDEX BY 4 FOR F.P. NUMBERS
≠MULF≡≡TENLST≡≡R3≡≡AC0≡≥	051644	171063	053164			MULF	TENLST(R3),AC0	;ADJUST EXPONENT OF NUMBER
≠JMP≡≡CDONE≡≥	051650	000167	000010			JMP	CDONE		;EXIT ROUTINE
≥					
≥					;CHECK IF END OF NUMBER
≥					
≠TST≡≡R4≡≥	051654	005704			CHKDN:	TST     R4		;COMPARE CHARACTER TO A NULL CHARACTER
≠BEQ≡≡CDONE≡≥	051656	001402				BEQ	CDONE		;EXIT IF IT IS, THIS IS THE END OF THE STR
≠TST≡≡R1≡≥	051660	005701				TST	R1		;TEST IF ANY DIGITS YET
≠BLT≡≡PICK≡≥	051662	002640				BLT	PICK		;IF NONE, KEEP SCANNING
≥					
≥					;NO MORE DIGITS - APPLY CORRECT SIGN TO NUMBER
≥					
≠MOV≡≡SP≡≡R4≡≥	051664	012604			CDONE:	MOV	(SP)+,R4	;RESTORE REGISTERS
≠MOV≡≡SP≡≡R3≡≥	051666	012603			     	MOV	(SP)+,R3
≠MOV≡≡SP≡≡R2≡≥	051670	012602				MOV	(SP)+,R2
≠DEC≡≡R0≡≥	051672	005300				DEC	R0		;POINT TO BREAK CHARACTER
≠TST≡≡MSIGN≡≥	051674	005767	000740		    	TST	MSIGN		;TEST SIGN OF MANTISSA
≠BEQ≡≥	051700	001401				BEQ	.+4
≠NEGF≡≡AC0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 204
	FLOAT PAL[HAL,HE]	PAGE 5.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	051702	170700				NEGF	AC0		;COMPLEMENT NUMBER IF SIGN NEGATIVE
≠RTS≡≡PC≡≥	051704	000207				RTS	PC		;RETURN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 205
	FLOAT PAL[HAL,HE]	PAGE 6 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;ROUTINES TO SET AND RESTORE OUTPUT FORMAT - "FORMAT"&"RSTFOR"
≥					
≥					;THE TOTAL NUMBER OF CHARACTERS TO BE WRITTEN (WIDTH) SHOULD BE
≥					;LOADED INTO R0 AND THE NUMBER OF DECIMAL DIGITS (DIGITS) SHOULD
≥					;BE LOADED INTO R1 BEFORE CALLING THIS ROUTINE.  IN ALL CASES,
≥					;WIDTH SHOULD BE GREATER THAN OR EQUAL TO DIGIT+2.  "FORMAT" IS
≥					;CALLED BY THE "SIMPLE METHOD".
≥					
≥					;REGISTERS USED:
≥					;
≥					;	R0,R1 PASS ARGUMENTS
≥					;	NO OTHER REGISTERS AFFECTED
≥					
≠MOV≡≡WIDTH≡≡OLDW≡≥	051706	016767	000740	000742	FORMAT:	MOV	WIDTH,OLDW	;SAVE THE OLD WIDTH
≠MOV≡≡DIG≡≡OLDD≡≥	051714	016767	000734	000736		MOV	DIG,OLDD	;   AND DIG
≠SUB≡≡R0≡≥	051722	162700	000002			SUB	#2,R0		;SUBTRACT SPACES FOR SIGN AND . FROM WIDTH
≠MOV≡≡R0≡≡WIDTH≡≥	051726	010067	000720			MOV	R0,WIDTH	;SAVE WIDTH OF I/O STRING - 2
≠MOV≡≡R1≡≡DIG≡≥	051732	010167	000716			MOV	R1,DIG		;SAVE THE NUMBER OF DECI. DIGITS
≠CMP≡≡R0≡≡R1≡≥	051736	020001				CMP	R0,R1		;CHECK TO SEE THAT WIDTH.GE.DIGIT+2
≠BGE≡≡NFER≡≥	051740	002012				BGE	NFER		;SKIP IF SPACE ALLOWED, ELSE CORRECT
≤OUTSTR≡≥						OUTSTR	FERM		;TYPE OUT ERROR MESSAGE
≠MOV≡≡R0≡≡SP≡≥	051742	010046				MOV R0,-(SP)	;Save R0.  Who knows what was happening in it?
≠MOV≡≡R1≡≡SP≡≥	051744	010146				MOV R1,-(SP)	;Save R1.
≠MOV≡≡FERM≡≡R0≡≥	051746	012700	051770			MOV #FERM,R0	;Load up the string to be output
≠JSR≡≡PC≡≡TYPSTR≡≥	051752	004767	742122			JSR PC,TYPSTR	;Call the string output utility routine.
≠MOV≡≡SP≡≡R1≡≥	051756	012601				MOV (SP)+,R1	;Restore R1.
≠MOV≡≡SP≡≡R0≡≥	051760	012600				MOV (SP)+,R0	;Restore R0.
≠MOV≡≡R1≡≡WIDTH≡≥	051762	010167	000664			MOV	R1,WIDTH	;SET WIDTH=DIG+2
≠RTS≡≡PC≡≥	051766	000207			NFER:	RTS	PC		;RETURN
≥					
≠.ASCIZ≡≥	051770	   015		
≥	051771	   012			FERM:	.ASCIZ /
≥	051772	   106		
≥	051773	   117		
≥	051774	   122		
≥	051775	   115		
≥	051776	   101		
≥	051777	   124		
≥	052000	   124		
≥	052001	   111		
≥	052002	   116		
≥	052003	   107		
≥	052004	   040		
≥	052005	   105		
≥	052006	   122		
≥	052007	   122		
≥	052010	   117		
≥	052011	   122		
≥	052012	   015		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 206
	FLOAT PAL[HAL,HE]	PAGE 6.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	052013	   012			FORMATTING ERROR
≥	052014	   000		
≥					/
≠.EVEN≡≥		052016				.EVEN
≥					
≥					
≥					;ROUTINE TO RESTORE LAST FORMAT - "RSTFOR"
≥					
≥					;THE PREVIOUS FORMAT BECOMES THE CURRENT FORMAT.  THE CURRENT
≥					;FORMAT IS LOST FOREVER.  "RSTFOR" IS CALLED IN THE "SIMPLE 
≥					;METHOD".
≥					
≥					;REGISTERS USED:  NONE
≥					
≠MOV≡≡OLDW≡≡WIDTH≡≥	052016	016767	000634	000626	RSTFOR:	MOV	OLDW,WIDTH	;RESTORE WIDTH
≠MOV≡≡OLDD≡≡DIG≡≥	052024	016767	000630	000622		MOV	OLDD,DIG	;RESTORE DIG
≠RTS≡≡PC≡≥	052032	000207				RTS	PC		;RETURN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 207
	FLOAT PAL[HAL,HE]	PAGE 7 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;FLOATING POINT NUMBER TO "F" FORMAT STRING ROUTINE - "CVF"
≥					
≥					;"CVF" - THE STRING GENERATED BY THIS ROUTINE IS SIMILAR TO "F" FORMAT
≥					;IN  FORTRAN.  IT  IS ASSUMED  THAT THE NUMBER  TO BE CONVERTED  IS IN
≥					;REGISTER AC0  AND R0  CONTAINS A  POINTER TO  THE FIRST  BYTE OF  THE
≥					;OUTPUT STRING.  THE NUMBER OF  CHARACTERS WRITTEN SHOULD FIRST BE SET
≥					;IN  A CALL  TO "FORMAT", ELSE  THE DEFAULT VALUES  ARE USED.   IF THE
≥					;INTEGER PART  OF  THE  NUMBER EXCEEDS  THE  FORMAT LIMITS  THE  FIRST
≥					;CHARACTER WRITTEN  IS A ">".   AFTER COMPLETION, "CVF"  LEAVES A NULL
≥					;CHARACTER FOLLOWING THE NUMBER STRING.  REGISTER R0 IS LEFT  POINTING
≥					;AT THE NULL CHARACTER.
≥					
≥					;REGISTERS USED:
≥					;
≥					;	R0,AC0 PASS ARGUMENTS
≥					;	R1,AC1 GARBAGED
≥					
≠MOV≡≡WIDTH≡≡R1≡≥	052034	016701	000612		CVF:	MOV	WIDTH,R1	;GET THE TOTAL NUMBER OF CHAR TO BE WRITTEN
≠SUB≡≡DIG≡≡R1≡≥	052040	166701	000610			SUB	DIG,R1		;DETERMINE THE MAG. OF THE M.S. DIGIT
≠MOV≡≡R1≡≡PT≡≥	052044	010167	000612			MOV	R1,PT		;NOW HAVE # OF DIGITS BEFORE DECIMAL POINT
≠ASH≡≡R1≡≥	052050	072127	000002			ASH	#2,R1		;X 4, USE AS INDEX INTO F.P. TABLE
≠DIVF≡≡TENLST≡≡R1≡≡AC0≡≥	052054	174461	053164			DIVF	TENLST(R1),AC0	;NORMALIZE NUMBER TO BETWEEN 0 AND .99999999
≠MOV≡≡WIDTH≡≡R1≡≥	052060	016701	000566			MOV	WIDTH,R1	;TOTAL # OF DIGITS TO R1
≠MOV≡≡R2≡≡SP≡≥	052064	010246				MOV	R2,-(SP)	;SAVE THE REGISTERS
≠MOV≡≡R3≡≡SP≡≥	052066	010346				MOV	R3,-(SP)
≠JSR≡≡PC≡≡PRTF≡≥	052070	004767	000344			JSR	PC,PRTF		;TYPE OUT THE DIGITS
≠MOVB≡≡R0≡≥	052074	112710	000000			MOVB	#0,(R0)		;PUT A NULL CHARACTER AFTER THE STRING
≠MOV≡≡SP≡≡R3≡≥	052100	012603				MOV	(SP)+,R3	;RESTORE THE REGISTERS
≠MOV≡≡SP≡≡R2≡≥	052102	012602				MOV	(SP)+,R2
≠RTS≡≡PC≡≥	052104	000207				RTS	PC		;RETURN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 208
	FLOAT PAL[HAL,HE]	PAGE 8 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;FLOATING POINT NUMBER TO "E" FORMAT STRING ROUTINE - "CVE"
≥					
≥					;"CVE" - SAME OPERATION AS "CVF" EXCEPT THAT OUTPUT IN FORTRAN "E" FORMAT
≥					
≠MOV≡≡R2≡≡SP≡≥	052106	010246			CVE:	MOV	R2,-(SP)	;SAVE THE REGISTERS
≠MOV≡≡R3≡≡SP≡≥	052110	010346				MOV 	R3,-(SP)
≠CLR≡≡EXPON≡≥	052112	005067	000526		        CLR     EXPON		;RESET EXPONENT COUNT
≠MOV≡≡PT≡≥	052116	012767	000001	000536		MOV	#1,PT		;SET COUNT TO PRINT 1 NUMBER BEFORE DECIMAL PT
≠MOV≡≡WIDTH≡≡R1≡≥	052124	016701	000522			MOV	WIDTH,R1	;SET COUNT FOR TOTAL NUMBER OF DIGITS TO BE SENT
≠SUB≡≡R1≡≥	052130	162701	000004			SUB	#4,R1		;ADJUST FOR EXPONENT
≠TSTF≡≡AC0≡≥	052134	170500				TSTF	AC0		;CHECK IF NUMBER IS ZERO
≠CFCC≡≠CFCC≡≥	052136	170000				CFCC			;TRANSFER CONDITIONAL CODES TO CPU
≠BEQ≡≡EPRT≡≥	052140	001445				BEQ	EPRT		;START PRINTING IF NUMBER IS 0.0
≠STF≡≡AC0≡≡NUM≡≥	052142	174067	000500		     	STF	AC0,NUM		;GET THE NUMBER TO BE CONVERTED
≠DEC≡≡EXPON≡≥	052146	005367	000472			DEC	EXPON		;ADJUST EXPONENT FOR PRINTING 1 INT. DIGIT
≠MOV≡≡NUM≡≡R2≡≥	052152	016702	000470			MOV	NUM,R2		;LOAD THE EXPONENT AND MSB OF THE NUMBER
≠BIC≡≡R2≡≥	052156	042702	100000			BIC	#100000,R2	;CONVERT TO ABSOLUTE VALUE
≠SUB≡≡R2≡≥	052162	162702	000150			SUB	#150,R2		;ADJUST EXPONENT DOWN
≠BGE≡≥	052166	002001				BGE	.+4
≠CLR≡≡R2≡≥	052170	005002				CLR	R2		;LEAVE IT POSITIVE
≠MUL≡≡R2≡≥	052172	070227	000233			MUL	#233,R2		;USE EXPONENT AND MSB AS INDEX INTO TEN TABLE
≠CMP≡≡R2≡≥	052176	020227	000114			CMP	R2,#76.		;COMPARE TO 1.0@38
≠BLE≡≥	052202	003402				BLE	.+6
≠MOV≡≡R2≡≥	052204	012702	000114			MOV	#76.,R2		;IF LARGER, REPLACE BY 1.0@38
≠SUB≡≡R2≡≥	052210	162702	000046		      	SUB	#38.,R2		;SHIFT INDEX INTO RANGE OF -38 TO +38
≠ADD≡≡R2≡≡EXPON≡≥	052214	060267	000424			ADD	R2,EXPON	;ADJUST EXPONENT COUNT
≠ASH≡≡R2≡≥	052220	072227	000002			ASH	#2,R2		;MULT INDEX BY 4 FOR FLOATING POINT NUMBERS
≠DIVF≡≡TENLST≡≡R2≡≡AC0≡≥	052224	174462	053164			DIVF	TENLST(R2),AC0	;NORMALIZE NUMBER INTO RANGE 0.0 TO 0.9999
≠STF≡≡AC0≡≡AC1≡≥	052230	174001				STF	AC0,AC1		;GET ABSOLUTE VALUE OF NUMBER
≠ABSF≡≡AC1≡≥	052232	170601				ABSF	AC1
≠CMPF≡≡TENLST≡≡AC1≡≥	052234	173567	000724			CMPF	TENLST,AC1	;CHECK IF NUMBER LESS THAN 1.0
≠CFCC≡≠CFCC≡≥	052240	170000				CFCC			;TRANSFER CONDITIONAL CODES TO CPU
≠BGT≡≡EPRT≡≥	052242	003004				BGT	EPRT		;IF ITS BETWEEN 0.0 AND .99999, GO TO PNTF
≠DIVF≡≡TEN≡≡AC0≡≥	052244	174467	000720			DIVF	TEN,AC0		;ELSE MULT. BY 0.1 AND ADJUST EXPONENT
≠INC≡≡EXPON≡≥	052250	005267	000370		        INC	EXPON
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 209
	FLOAT PAL[HAL,HE]	PAGE 9 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥						[CONTINUATION OF "CVE"]
≥					
≠JSR≡≡PC≡≡PRTF≡≥	052254	004767	000160		EPRT:	JSR	PC,PRTF		;GO PRINT MANTISSA
≠MOVB≡≡R0≡≥	052260	112720	000105			MOVB	#105,(R0)+	;PUT A "E" CHAR INTO THE STRING
≠MOVB≡≡R0≡≥	052264	112720	000053			MOVB	#53,(R0)+	;ASSUME EXPONENT POSITIVE A OUTPUT A "+"
≠MOV≡≡EXPON≡≡R3≡≥	052270	016703	000350			MOV	EXPON,R3	;TEST SIGN OF EXPONENT
≠BGE≡≡XPRT≡≥	052274	002004				BGE	XPRT		;SKIP IF POSITIVE
≠MOVB≡≡R0≡≥	052276	112760	000055	777777		MOVB	#55,-1(R0)	;REPLACE "+" WITH "-"
≠NEG≡≡R3≡≥	052304	005403				NEG	R3    		;MAKE EXPONENT POSITIVE
≠CLR≡≡R2≡≥	052306	005002			XPRT:	CLR	R2		;CLEAR FOR DIVISION
≠DIV≡≡R2≡≥	052310	071227	000012		     	DIV	#10.,R2		;SEPARATES TENS AND UNITS DIGIT
≠BIS≡≡R2≡≥	052314	052702	000060			BIS	#60,R2		;CONVERT TO ASC AND PUT IN I/O BUFFER
≠MOVB≡≡R2≡≡R0≡≥	052320	110220				MOVB	R2,(R0)+
≠BIS≡≡R3≡≥	052322	052703	000060			BIS	#60,R3
≠MOVB≡≡R3≡≡R0≡≥	052326	110320				MOVB	R3,(R0)+
≠MOVB≡≡R0≡≥	052330	112710	000000			MOVB	#0,(R0)		;PUT IN A NULL CHARACTER
≠MOV≡≡SP≡≡R3≡≥	052334	012603				MOV	(SP)+,R3	;RESTORE THE REGISTERS
≠MOV≡≡SP≡≡R2≡≥	052336	012602				MOV	(SP)+,R2
≠RTS≡≡PC≡≥	052340	000207				RTS	PC		;RETURN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 210
	FLOAT PAL[HAL,HE]	PAGE 10 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;FLOATING POINT NUMBER TO "E" OR "F" FORMAT STRING  - "CVG"
≥					
≥					;"CVG" - DETERMINES IF THE NUMBER IN AC0 CAN BE WRITTEN BY "CVF", IF
≥					;IT CAN, THEN CVF IS CALLED, ELSE THE NUMBER IS PRINTED USING "CVE".
≥					
≠LDF≡≡AC0≡≡AC1≡≥	052342	172500			CVG:	LDF	AC0,AC1		;COPY THE  NUMBER
≠CFCC≡≠CFCC≡≥	052344	170000				CFCC			;TRANSFER THE CONDITIONAL CODES TO CPU
≠ABSF≡≡AC1≡≥	052346	170601				ABSF	AC1		;CONVERT NUMBER TO ABSOLUTE VALUES
≠BEQ≡≡RUNF≡≥	052350	001430				BEQ	RUNF		;IF NUMBER = 0.0, EXECUTE CVF
≠MOV≡≡DIG≡≡R1≡≥	052352	016701	000276			MOV	DIG,R1		;GET THE NUMBER OF DECIMAL DIGITS TO BE TYPED
≠ASH≡≡R1≡≥	052356	072127	000002			ASH	#2,R1		;MULT BY 4 TO USE A FLOATING POINT INDEX
≠MULF≡≡TENLST≡≡R1≡≡AC1≡≥	052362	171161	053164			MULF	TENLST(R1),AC1	;CHECK IF NUMBER SMALLER THAN 1.0@-DIG
≠CMPF≡≡TENLST≡≡AC1≡≥	052366	173567	000572			CMPF	TENLST,AC1	;COMPARE TO 1.0
≠CFCC≡≠CFCC≡≥	052372	170000				CFCC			;TRANSFER CONDITIONAL CODES TO CPU
≠BGT≡≡RUNE≡≥	052374	003013				BGT	RUNE		;IF LESS THAN 1.0@-DIG, PRINT USING CVE
≠MOV≡≡WIDTH≡≡R1≡≥	052376	016701	000250			MOV	WIDTH,R1	;GET THE TOTAL NUMBER OF DIGITS TO BE PRINTED
≠ASH≡≡R1≡≥	052402	072127	000002			ASH	#2,R1		;USE THIS AS A F.P. INDEX
≠NEG≡≡R1≡≥	052406	005401				NEG	R1
≠MULF≡≡TENLST≡≡R1≡≡AC1≡≥	052410	171161	053164			MULF	TENLST(R1),AC1	;CHECK IF GREATER THAN WIDTH-DIG LONG
≠CMPF≡≡TENLST≡≡AC1≡≥	052414	173567	000544			CMPF	TENLST,AC1	;COMPARE TO 1.0
≠CFCC≡≠CFCC≡≥	052420	170000				CFCC			;TRANSFER CONDITIONAL CODES
≠BGE≡≡RUNF≡≥	052422	002003				BGE	RUNF		;IF TOO LARGE, USE CVE
≠JSR≡≡PC≡≡CVE≡≥	052424	004767	777456		RUNE:	JSR	PC,CVE
≠RTS≡≡PC≡≥	052430	000207				RTS	PC
≠JSR≡≡PC≡≡CVF≡≥	052432	004767	777376		RUNF:	JSR	PC,CVF
≠RTS≡≡PC≡≥	052436	000207				RTS	PC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 211
	FLOAT PAL[HAL,HE]	PAGE 11 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;	PRINTING ROUTINE USED BY "CVF" & "CVE"
≥					
≠TSTF≡≡AC0≡≥	052440	170500			PRTF:	TSTF	AC0		;TEST THE SIGN OF THE NUMBER
≠MOVB≡≡MSIGN≡≥	052442	112767	000040	000170		MOVB	#40,MSIGN	;ASSUME SIGN POSITIVE
≠CFCC≡≠CFCC≡≥	052450	170000				CFCC			;TRANSFER THE CONDITIONAL CODES TO CPU
≠ABSF≡≡AC0≡≥	052452	170600				ABSF	AC0		;CLEAR THE SIGN OF THE NUMBER
≠BGE≡≥	052454	002003				BGE	.+10		
≠MOVB≡≡MSIGN≡≥	052456	112767	000055	000154	  	MOVB	#55,MSIGN	;IF NEGATIVE PUT IN "-" SIGN
≠MODF≡≡TEN≡≡AC0≡≥	052464	171467	000500			MODF	TEN,AC0		;COMPUTE M.S. INTEGER DIGIT
≠CLR≡≡R3≡≥	052470	005003				CLR	R3		;INDICATE SIGN NOT YET WRITTEN
≠TST≡≡PT≡≥	052472	005767	000164		DIGLP:	TST	PT		;CHECK IF TIME TO PRINT DECIMAL POINT
≠BNE≡≡GETDG≡≥	052476	001007				BNE	GETDG		;SKIP IF NOT
≠TST≡≡R3≡≥	052500	005703				TST	R3		;HAVE WE PRINTED SIGN YET?
≠BNE≡≡WTDP≡≥	052502	001003				BNE	WTDP		;SKIP IF WE HAVE
≠MOVB≡≡MSIGN≡≡R0≡≥	052504	116720	000130			MOVB	MSIGN,(R0)+	;ELSE PRINT SIGN BEFORE DECIMAL POINT
≠INC≡≡R3≡≥	052510	005203				INC	R3		;INDICATE SIGN PRINTED
≠MOVB≡≡R0≡≥	052512	112720	000056		WTDP:	MOVB	#56,(R0)+	;PRINT DECIMAL POINT
≠STCFI≡≡AC1≡≡R2≡≥	052516	175502			GETDG:	STCFI	AC1,R2 		;SAVE M.S. INTEGER DIGIT
≠CFCC≡≠CFCC≡≥	052520	170000				CFCC			;CHECK FOR NUMBER TOO LARGE TO INTEGERIZE
≠BCC≡≡CHKSZ≡≥	052522	103015				BCC	CHKSZ
≠ADDF≡≡AC1≡≡AC0≡≥	052524	172001			TOLGE:	ADDF	AC1,AC0		;IF TWO LARGE, PUT IT BACK TOGETHER
≠MODF≡≡TENTH≡≡AC0≡≥	052526	171467	000426			MODF	TENTH,AC0	;SCALE DOWN AND TRY INTEGERIZING AGAIN
≠INC≡≡R1≡≥	052532	005201				INC	R1		;PRINT OUT ONE MORE DIGIT
≠INC≡≡PT≡≥	052534	005267	000122			INC	PT		;SHIFT DECIMAL POINT TO PUT IN EXTRA DIGIT
≠TST≡≡R3≡≥	052540	005703				TST	R3		;CHECK IF SIGN AND D.P. ALREADY WRITTEN
≠BEQ≡≡GETDG≡≥	052542	001765				BEQ	GETDG		;GO CHECK IF IN RANGE IF NOT WRITTEN
≠CLR≡≡R3≡≥	052544	005003				CLR	R3		;CLEAR SIGN AND D.P.
≠SUB≡≡R0≡≥	052546	162700	000002			SUB	#2,R0		;ADJUST BYTE POINTER
≠JMP≡≡GETDG≡≥	052552	000167	777740			JMP	GETDG		;GO CHECK IF IN RANGE AGAIN
≠TST≡≡R2≡≥	052556	005702			CHKSZ:	TST     R2              ;TEST INTEGER
≠BLT≡≡TOLGE≡≥	052560	002761				BLT	TOLGE		;IF TOO LARGE, GO SCALE AGAIN
≠CMP≡≡R2≡≥	052562	020227	000011			CMP	R2,#9.		;CHECK IF LESS THAN 9
≠BGT≡≡TOLGE≡≥	052566	003356				BGT	TOLGE		;SCALE IF GREATER THAN 9
≠MODF≡≡TEN≡≡AC0≡≥	052570	171467	000374		      	MODF	TEN,AC0		;START COMPUTING NEXT INTEGER DIGIT
≠TST≡≡R3≡≥	052574	005703				TST	R3		;HAVE WE PRINTED SIGN YET?
≠BNE≡≡SETBS≡≥	052576	001005				BNE	SETBS		;SKIP IF WE HAVE
≠TST≡≡R2≡≥	052600	005702				TST	R2		;CHECK IF LEADING ZERO
≠BEQ≡≡WTSP≡≥	052602	001407				BEQ	WTSP		;IF IT IS GO WRITE A SPACE CHARACTER
≠MOVB≡≡MSIGN≡≡R0≡≥	052604	116720	000030			MOVB	MSIGN,(R0)+	;FIRST CHARACTER, NOW PRINT SIGN
≠INC≡≡R3≡≥	052610	005203				INC	R3		;INDICATE SIGN PRINTED
≠BIS≡≡R2≡≥	052612	052702	000060		SETBS:	BIS	#60,R2		;SET ASC ZERO BASE
≠JMP≡≡WTCH≡≥	052616	000167	000004			JMP	WTCH
≠MOVB≡≡R2≡≥	052622	112702	000040		WTSP:	MOVB	#40,R2		;WRITE A SPACE CHARACTER
≠MOVB≡≡R2≡≡R0≡≥	052626	110220			WTCH:	MOVB	R2,(R0)+	;PUT CHARACTER IN I/O BUFFER
≠DEC≡≡PT≡≥	052630	005367	000026			DEC	PT		;DECREMENT DECIMAL POINT COUNT
≠SOB≡≡R1≡≡DIGLP≡≥	052634	077162				SOB	R1,DIGLP	;DONE WITH CHARACTERS?
≠RTS≡≡PC≡≥	052636	000207				RTS	PC		;RETURN
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 212
	FLOAT PAL[HAL,HE]	PAGE 12 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;LOCAL STORAGE AREA
≥					
≥	052640	000000			MSIGN:	0		;SIGN OF CURRENT NUMBER
≥	052642	000000			ESIGN:	0		;SIGN OF EXPONENT
≥	052644	000000			EXPON:	0
≠.WORD≡≥	052646	000000		
≥	052650	000000			NUM:	.WORD  0,0
≥	052652	000010			WIDTH:	8. 		;DEFAULT NUMBER OF CHARACTERS IN OUTPUT STRING
≥	052654	000003			DIG:	3		;DEFAULT NUMBER OF DECIMAL DIGITS
≥	052656	000010			OLDW:	8.		;OLD VALUES OF WIDTH AND DIG
≥	052660	000003			OLDD:	3
≥	052662	000000			PT:	0		;NUMBER OF DIGITS BEFORE DECIMAL POINT
≥					
≥					;TABLE OF F.P. DIGITS FROM 0 TO 9.0
≥					
≠.WORD≡≥	052664	000000		
≥	052666	000000		
≥	052670	040200		
≥	052672	000000		
≥	052674	040400		
≥	052676	000000		
≥	052700	040500		
≥	052702	000000			DGLST:	.WORD        0,     0, 40200,     0, 40400,     0, 40500,     0
≠.WORD≡≥	052704	040600		
≥	052706	000000		
≥	052710	040640		
≥	052712	000000		
≥	052714	040700		
≥	052716	000000		
≥	052720	040740		
≥	052722	000000				.WORD    40600,     0, 40640,     0, 40700,     0, 40740,     0
≠.WORD≡≥	052724	041000		
≥	052726	000000		
≥	052730	041020		
≥	052732	000000				.WORD    41000,     0, 41020,     0
≥					
≥					;TABLE OF POWERS OF TEN
≥					
≠.WORD≡≥	052734	000531		
≥	052736	143735		
≥	052740	001410		
≥	052742	016352		
≥	052744	002252		
≥	052746	022045		
≥	052750	003124		
≥	052752	126456				.WORD      531,143735,  1410, 16352,  2252, 22045,  3124,126456
≠.WORD≡≥	052754	004004		
≥	052756	166075		
≥	052760	004646		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 213
	FLOAT PAL[HAL,HE]	PAGE 12.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	052762	023514		
≥	052764	005517		
≥	052766	130437		
≥	052770	006401		
≥	052772	147263				.WORD	  4004,166075,  4646, 23514,  5517,130437,  6401,147263
≠.WORD≡≥	052774	007242		
≥	052776	041140		
≥	053000	010112		
≥	053002	151370		
≥	053004	010775		
≥	053006	103666		
≥	053010	011636		
≥	053012	072322				.WORD	  7242, 41140, 10112,151370, 10775,103666, 11636, 72322
≠.WORD≡≥	053014	012506		
≥	053016	011006		
≥	053020	013367		
≥	053022	113210		
≥	053024	014232		
≥	053026	137025		
≥	053030	015101		
≥	053032	066632				.WORD	 12506, 11006, 13367,113210, 14232,137025, 15101, 66632
≠.WORD≡≥	053034	015761		
≥	053036	144400		
≥	053040	016627		
≥	053042	016640		
≥	053044	017474		
≥	053046	162410		
≥	053050	020354		
≥	053052	017113				.WORD	 15761,144400, 16627, 16640, 17474,162410, 20354, 17113
≠.WORD≡≥	053054	021223		
≥	053056	111357		
≥	053060	022070		
≥	053062	073652		
≥	053064	022746		
≥	053066	112625		
≥	053070	023620		
≥	053072	016575				.WORD	 21223,111357, 22070, 73652, 22746,112625, 23620, 16575
≠.WORD≡≥	053074	024464		
≥	053076	022334		
≥	053100	025341		
≥	053102	027023		
≥	053104	026214		
≥	053106	136314		
≥	053110	027057		
≥	053112	165777				.WORD	 24464, 22334, 25341, 27023, 26214,136314, 27057,165777
≠.WORD≡≥	053114	027733		
≥	053116	163377		
≥	053120	030611		
≥	053122	070137		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 214
	FLOAT PAL[HAL,HE]	PAGE 12.2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	053124	031453		
≥	053126	146167		
≥	053130	032326		
≥	053132	137625				.WORD	 27733,163377, 30611, 70137, 31453,146167, 32326,137625
≠.WORD≡≥	053134	033206		
≥	053136	033675		
≥	053140	034047		
≥	053142	142654		
≥	053144	034721		
≥	053146	133427		
≥	053150	035603		
≥	053152	011157				.WORD	 33206, 33675, 34047,142654, 34721,133427, 35603, 11157
≠.WORD≡≥	053154	036443		
≥	053156	153412				.WORD	 36443,153412
≠.WORD≡≥	053160	037314		
≥	053162	146315			TENTH:	.WORD	 37314,146315 
≠.WORD≡≥	053164	040200		
≥	053166	000000			TENLST:	.WORD	 40200,     0 
≠.WORD≡≥	053170	041040		
≥	053172	000000			TEN:	.WORD	 41040,     0
≠.WORD≡≥	053174	041710		
≥	053176	000000		
≥	053200	042572		
≥	053202	000000		
≥	053204	043434		
≥	053206	040000		
≥	053210	044303		
≥	053212	050000				.WORD	 41710,     0, 42572,     0, 43434, 40000, 44303, 50000
≠.WORD≡≥	053214	045164		
≥	053216	022000		
≥	053220	046030		
≥	053222	113200		
≥	053224	046676		
≥	053226	136040		
≥	053230	047556		
≥	053232	065450				.WORD	 45164, 22000, 46030,113200, 46676,136040, 47556, 65450
≠.WORD≡≥	053234	050425		
≥	053236	001371		
≥	053240	051272		
≥	053242	041667		
≥	053244	052150		
≥	053246	152245		
≥	053250	053021		
≥	053252	102347				.WORD	 50425,  1371, 51272, 41667, 52150,152245, 53021,102347
≠.WORD≡≥	053254	053665		
≥	053256	163041		
≥	053260	054543		
≥	053262	057651		
≥	053264	055416		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 215
	FLOAT PAL[HAL,HE]	PAGE 12.3 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	053266	015712		
≥	053270	056261		
≥	053272	121274				.WORD	 53665,163041, 54543, 57651, 55416, 15712, 56261,121274
≠.WORD≡≥	053274	057136		
≥	053276	005553		
≥	053300	060012		
≥	053302	143443		
≥	053304	060655		
≥	053306	074354		
≥	053310	061530		
≥	053312	153447				.WORD	 57136,  5553, 60012,143443, 60655, 74354, 61530,153447
≠.WORD≡≥	053314	062407		
≥	053316	103170		
≥	053320	063251		
≥	053322	064026		
≥	053324	064123		
≥	053326	141034		
≥	053330	065004		
≥	053332	054521				.WORD	 62407,103170, 63251, 64026, 64123,141034, 65004, 54521
≠.WORD≡≥	053334	065645		
≥	053336	067646		
≥	053340	066516		
≥	053342	145617		
≥	053344	067401		
≥	053346	037472		
≥	053350	070241		
≥	053352	107410				.WORD	 65645, 67646, 66516,145617, 67401, 37472, 70241,107410
≠.WORD≡≥	053354	071111		
≥	053356	171312		
≥	053360	071774		
≥	053362	067574		
≥	053364	072635		
≥	053366	142656		
≥	053370	073505		
≥	053372	033431				.WORD	 71111,171312, 71774, 67574, 72635,142656, 73505, 33431
≠.WORD≡≥	053374	074366		
≥	053376	102337		
≥	053400	075232		
≥	053402	011414		
≥	053404	076100		
≥	053406	113717		
≥	053410	076760		
≥	053412	136702				.WORD	 74366,102337, 75232, 11414, 76100,113717, 76760,136702
≠.WORD≡≥	053414	077626		
≥	053416	073231				.WORD	 77626, 73231
≥					
≥					;This is the end of the floating package.
≥					.ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 216
	HAL PAL[HAL,HE]	PAGE 2.5 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					.ENDC
≥					
≠.IFNZ≡≡ALAID≡≥		000001			.IFNZ ALAID		;The debugging package
≡FLOAT≠≥		000001			    FLOAT==1		;uses floating output
≠.INSRT≡≥					    .INSRT ALAID.PAL[HAL,HE]
≠COMMEN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 217
	ALAID PAL[HAL,HE]	PAGE 1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥				COMMENT ⊗   VALID 00016 PAGES
≥				C REC  PAGE   DESCRIPTION
≥				C00001 00001
≥				C00003 00002	  FILES, SETNAM
≥				C00005 00003	  Data structures:  Notes, note cells, message buffers
≥				C00009 00004	  GETNOTE, SNDNOTE, SERVER
≥				C00013 00005	  DOGTBUF, DOUSBUF, DORLBUF
≥				C00015 00006	  LINKQUEUE, UNLQUE, SAMEID
≥				C00018 00007	  TREATMESSAGE, GETOFS, DOERR, SNDANS
≥				C00024 00008	  MAKREQ, SNDREQ
≥				C00028 00009	  KTABLE, RTABLE, LOOKUP, RLOOKP, GETOCT, ascie messages
≥				C00036 00010	   TACK, SKIPSP, SKIPOPT
≥				C00038 00011	  DOGETVAL, DOSETVAL
≥				C00047 00012	  DOWAIT, DOSIGNAL
≥				C00052 00013	  DOSETNAM
≥				C00056 00014	  DOSTART, DODDT, DONOTICE
≥				C00062 00015	  Driver for test of communications, ALINIT
≥				C00066 00016	  BUGS
≥				C00067 ENDMK
≥					C⊗;
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 218
	ALAID PAL[HAL,HE]	PAGE 2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  FILES, SETNAM
≥					
≥					
≠.IFNDF≡≡INTLOA≡≥					.IFNDF INTLOAD
≥					    DEBUG == 1
≥					.IFF
≡DEBUG≠≥		000000			    DEBUG == 0
≥					.ENDC
≥					
≡KERNEL≠≥		000001			KERNEL == 1
≡FLOAT≠≥		000001			FLOAT == 1
≥					
≠.IFNZ≡≡DEBUG≡≥		000000			.IFNZ DEBUG
≥					    .IF1
≥					        .TITLE  Test of ALAID
≥					        .INSRT HALHED.PAL[HAL,HE]
≥					        .INSRT K1DEF.PAL[11,SYS]
≥					    .ENDC
≥					
≥					    .=INTRP
≥					    .INSRT HALIO.PAL[HAL,HE]
≥					    .INSRT FLOAT.PAL[HAL,HE]
≥						STSW  LBDEBUG,1	;1 => first word of any large block is address of maker.
≥					    .INSRT LARGEB.PAL[HAL,HE]
≥					    INSTSZ == 20    ;Size of an interpreter stack
≥					.ENDC
≥					
≥					
≠.IFZ≡≡DEBUG≡≥		000000			.IFZ DEBUG
≥					
≥					;  Special pseudo-ops
≥					
≥					SETNAM:	;Interpreter code
≠MOV≡≡IPC≡≡R4≡≡INTNAM≡≡R4≡≥	053420	017464	000000	000026		MOV @IPC(R4),INTNAM(R4)
≤BMPIPC≡≥						BMPIPC		;
≠ADD≡≡IPC≡≡R4≡≥	053426	062764	000002	000000		ADD #2,IPC(R4)	;Bump IPC
≤CCC≡≥						CCC		;Clear Condition Code
≥					;	CLR R0		;Clear condition code.  Not used right now.
≠RTS≡≡PC≡≥	053434	000207				RTS PC		;Done
≥					.ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 219
	ALAID PAL[HAL,HE]	PAGE 3 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  Data structures:  Notes, note cells, message buffers
≥					
≥					;  Notes from 10 to 11:
≡GETBUF≠≥		000001			GETBUF == 1	;
≡USEBUF≠≥		000002			USEBUF == 2	;
≡RELBUF≠≥		000003			RELBUF == 3	;
≥					
≥					;  Notes from 11 to 10:
≡BUFALC≠≥		000101			BUFALC == 101	;
≡TAKBUF≠≥		000102			TAKBUF == 102	;
≥					
≥					;  Offsets in notes:
≡ARG1≠≥		000002			ARG1 == 2
≡ARG2≠≥		000004			ARG2 == 4
≥					
≥					;  Offsets in message buffers:
≡MESID≠≥		000000			MESID == 0	;
≡MESTYP≠≥		000002			MESTYP == 2	;
≡FROMTE≠≥		000001			    FROMTEN == 1	;
≡FROMEL≠≥		000002			    FROMELF == 2	;
≡REQUES≠≥		000004			    REQUEST == 4	;
≡ANSWER≠≥		000010			    ANSWER == 10	;
≡MESLTH≠≥		000004			MESLTH == 4	;
≡MESBEG≠≥		000006			MESBEG == 6	;
≥					
≡NOTB10≠≥		157000			NOTB10 = 157000 ;  The notebox from 11 to the 10 (byte address)
≡NOTB11≠≥		157020			NOTB11 = 157020 ;  The notebox from 10 to the 11 (byte address)
≥					
≡NOTSIZ≠≥		000003			NOTSIZ == 3		;  In WORDS!
≡BUFSIZ≠≥		000200			BUFSIZ == 200		;  In WORDS!
≥					
≠.WORD≡≥	053436	000000			NXTID:	.WORD 0	;Always even
≠.WORD≡≥	053440	000000			CURNAM:	.WORD 0	;The current ISB for active interpreter.
≥					
≥					;  Answer block:
≡II≠≥		000000				II == 0
≤XX≡≥						XX ANSBUF	;Points to a buffer for the return answer
≠.IFDF≡≡ANSBUF≡≥						   .IFDF ANSBUF
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using ANSBUF in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡ANSBUF≠≥		000000				    ANSBUF == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX ANPTR	;Initialized to point to the start of the message in ANSBUF
≠.IFDF≡≡ANPTR≡≥						   .IFDF ANPTR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using ANPTR in two ways!!!
≥						       .ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 220
	ALAID PAL[HAL,HE]	PAGE 3.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥						   .ENDC
≡II≡≡ANPTR≠≥		000002				    ANPTR == II
≡II≡≡II≠≥		000004				    II == II+2
≤XX≡≥						XX AGBUF	;Start of the request buffer
≠.IFDF≡≡AGBUF≡≥						   .IFDF AGBUF
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using AGBUF in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡AGBUF≠≥		000004				    AGBUF == II
≡II≡≡II≠≥		000006				    II == II+2
≤XX≡≥						XX AGARG	;Start of the arguments in request buffer
≠.IFDF≡≡AGARG≡≥						   .IFDF AGARG
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using AGARG in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡AGARG≠≥		000006				    AGARG == II
≡II≡≡II≠≥		000010				    II == II+2
≤XX≡≥						XX AGPTR	;Points to the current place in the request
≠.IFDF≡≡AGPTR≡≥						   .IFDF AGPTR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using AGPTR in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡AGPTR≠≥		000010				    AGPTR == II
≡II≡≡II≠≥		000012				    II == II+2
≤XX≡≥						XX VALPTR	;The value to be used in the answer
≠.IFDF≡≡VALPTR≡≥						   .IFDF VALPTR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using VALPTR in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡VALPTR≠≥		000012				    VALPTR == II
≡II≡≡II≠≥		000014				    II == II+2
≤XX≡≥						XX GPHPTR	;The graph node to be used in the answer
≠.IFDF≡≡GPHPTR≡≥						   .IFDF GPHPTR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using GPHPTR in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡GPHPTR≠≥		000014				    GPHPTR == II
≡II≡≡II≠≥		000016				    II == II+2
≡II≡≡ABKSIZ≠≥		000007				ABKSIZ == II/2	;Size of an answer block, in words.
≥					
≥					;  Request block:
≡II≠≥		000000				II == 0
≤XX≡≥						XX REQBUF	;Place where the request will be assembled
≠.IFDF≡≡REQBUF≡≥						   .IFDF REQBUF
≠.IF1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 221
	ALAID PAL[HAL,HE]	PAGE 3.2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥						       .IF1
≥						       .ERROR You are using REQBUF in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡REQBUF≠≥		000000				    REQBUF == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX REQPTR	;Current end of the assembled request
≠.IFDF≡≡REQPTR≡≥						   .IFDF REQPTR
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using REQPTR in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡REQPTR≠≥		000002				    REQPTR == II
≡II≡≡II≠≥		000004				    II == II+2
≤XX≡≥						XX REQRES	;Where the response is placed
≠.IFDF≡≡REQRES≡≥						   .IFDF REQRES
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using REQRES in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡REQRES≠≥		000004				    REQRES == II
≡II≡≡II≠≥		000006				    II == II+2
≤XX≡≥						XX REQEVT	;The event that will signal the return of the response
≠.IFDF≡≡REQEVT≡≥						   .IFDF REQEVT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using REQEVT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡REQEVT≠≥		000006				    REQEVT == II
≡II≡≡II≠≥		000010				    II == II+2
≤XX≡≥						XX REQQUE	;The queue node holding our waiting process
≠.IFDF≡≡REQQUE≡≥						   .IFDF REQQUE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using REQQUE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡REQQUE≠≥		000010				    REQQUE == II
≡II≡≡II≠≥		000012				    II == II+2
≡II≡≡RQBSIZ≠≥		000005				RQBSIZ == II/2	;Size in WORDS.
≥					
≥					;  Interlock event
≠.WORD≡≥	053442	000000			ALDEVT:	.WORD 0
≥					
≥					;  Waitqueue structure:
≡II≠≥		000000				II == 0
≤XX≡≥						XX QNEXT	;Next entry on queue
≠.IFDF≡≡QNEXT≡≥						   .IFDF QNEXT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using QNEXT in two ways!!!
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 222
	ALAID PAL[HAL,HE]	PAGE 3.3 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥						       .ENDC
≥						   .ENDC
≡II≡≡QNEXT≠≥		000000				    QNEXT == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX QPREV	;Previous entry on queue
≠.IFDF≡≡QPREV≡≥						   .IFDF QPREV
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using QPREV in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡QPREV≠≥		000002				    QPREV == II
≡II≡≡II≠≥		000004				    II == II+2
≡II≡≡QID≠≥		000004				   QID == II	;Identifier of this node.  Same field as QEVT.
≤XX≡≥						XX QEVT		;The event this waiter is expecting
≠.IFDF≡≡QEVT≡≥						   .IFDF QEVT
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using QEVT in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡QEVT≠≥		000004				    QEVT == II
≡II≡≡II≠≥		000006				    II == II+2
≤XX≡≥						XX QBUF		;The answer he was waiting for
≠.IFDF≡≡QBUF≡≥						   .IFDF QBUF
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using QBUF in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡QBUF≠≥		000006				    QBUF == II
≡II≡≡II≠≥		000010				    II == II+2
≡II≡≡QUELTH≠≥		000004				QUELTH == II/2	;Length of queue node in WORDS.
≥					
≠.BLKW≡≡QUELTH≡≥		053454			WAITQ:	.BLKW QUELTH	;List of processes waiting to hear answers.
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 223
	ALAID PAL[HAL,HE]	PAGE 4 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  GETNOTE, SNDNOTE, SERVER
≥					
≠COMMEN≡≥				COMMENT ⊗ Since there is only one server, it is not necessary to put
≥					any interlocks around code in GETNOTE and SNDNOTE.  ⊗
≥					
≥					GETNOTE:
≠COMMEN≡≥					COMMENT ⊗ Returns the first note seen in a block pointed to by R0. ⊗
≠MOV≡≡R2≡≡SP≡≥	053454	010246				MOV R2,-(SP)	;Save R2
≠TST≡≡NOTB11≡≥	053456	005767	103336		1$:	TST NOTB11	;Anything there?
≠BNE≡≥	053462	001004				BNE 2$		;Yes
≤SLEEP≡≥						SLEEP #100	;and sleep a while
≤.ARG≡≥						  .ARG #100
≠.LIF≡≥						    .LIF NB #100
≠MOV≡≡SP≡≥	053464	012746	000100			      MOV #100,-(SP)
≥	053470	104014				104014
≠BR≡≥	053472	000771				BR  1$		;And try again
≠MOV≡≡NOTSIZ≡≡R0≡≥	053474	012700	000003		2$:	MOV #NOTSIZ,R0	;
≠MOV≡≡R0≡≡R2≡≥	053500	010002				MOV R0,R2	;R2 ← Count of how many words to transfer
≠JSR≡≡PC≡≡GTFREE≡≥	053502	004767	754540			JSR PC,GTFREE	;R0 ← place to store the note
≠MOV≡≡NOTB11≡≡R1≡≥	053506	012701	157020			MOV #NOTB11,R1	;Transfer the note
≠MOV≡≡R1≡≡R0≡≥	053512	012120			3$:	MOV (R1)+,(R0)+	;
≠SOB≡≡R2≡≥	053514	077202				SOB R2,3$	;Repeat
≠SUB≡≡NOTSIZ≡≡R0≡≥	053516	162700	000006			SUB #2*NOTSIZ,R0	;Reset R0 to point to front of note.
≠CLR≡≡NOTB11≡≥	053522	005067	103272			CLR NOTB11	;Clear the note, to say we got it.
≠MOV≡≡SP≡≡R2≡≥	053526	012602				MOV (SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	053530	000207				RTS PC		;Done
≥					
≥					SNDNOTE:
≠COMMEN≡≥				COMMENT ⊗ R0 points to a note to send.  Send it and then release the
≥					block. ⊗
≠MOV≡≡R2≡≡SP≡≥	053532	010246				MOV R2,-(SP)	;Sve R2
≠TST≡≡NOTB10≡≥	053534	005767	103240		1$:	TST NOTB10	;Anything there?
≠BEQ≡≥	053540	001404				BEQ 2$		;No.
≤SLEEP≡≥						SLEEP #100	;Yes, so sleep a while
≤.ARG≡≥						  .ARG #100
≠.LIF≡≥						    .LIF NB #100
≠MOV≡≡SP≡≥	053542	012746	000100			      MOV #100,-(SP)
≥	053546	104014				104014
≠BR≡≥	053550	000771				BR  1$		;And try again
≠MOV≡≡NOTSIZ≡≡R1≡≥	053552	012701	000002		2$:	MOV #NOTSIZ-1,R1	;R1 ← count of words to send
≠MOV≡≡NOTB10≡≡R2≡≥	053556	012702	157002			MOV #NOTB10+2,R2;R2 ← Where to put it.
≠TST≡≡R0≡≥	053562	005720				TST (R0)+	;Skip the first word; we will put it in last
≠MOV≡≡R0≡≡R2≡≥	053564	012022			3$:	MOV (R0)+,(R2)+	;
≠SOB≡≡R1≡≥	053566	077102				SOB R1,3$	;Repeat
≠SUB≡≡NOTSIZ≡≡R0≡≥	053570	162700	000006			SUB #2*NOTSIZ,R0	;Reset R0 ← LOC[note]
≠MOV≡≡R0≡≡NOTB10≡≥	053574	011067	103200			MOV (R0),NOTB10	;Activate the note by sending the first word
≠JSR≡≡PC≡≡RLFREE≡≥	053600	004767	755004			JSR PC,RLFREE	;Release the block.
≠MOV≡≡SP≡≡R2≡≥	053604	012602				MOV (SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	053606	000207				RTS PC		;Done
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 224
	ALAID PAL[HAL,HE]	PAGE 4.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					
≥					SERVER:
≠COMMEN≡≥				COMMENT ⊗ Listens for notes from the 10 and acts on them.  Never
≥					returns. Uses R2. ⊗
≠JSR≡≡PC≡≡GETNOT≡≥	053610	004767	777640			JSR  PC,GETNOTE	;R0 ← LOC[note]
≠MOV≡≡R0≡≡R1≡≥	053614	011001				MOV (R0),R1	;R1 ← type of note
≠MOV≡≡R0≡≡R2≡≥	053616	010002				MOV R0,R2 	;R2 ← LOC[note]
≥					
≠CMP≡≡R1≡≡GETBUF≡≥	053620	020127	000001			CMP R1,#GETBUF	;GETBUF
≠BNE≡≥	053624	001003				BNE 1$ 
≠JSR≡≡PC≡≡DOGTBU≡≥	053626	004767	000114			JSR PC,DOGTBUF	;
≠BR≡≥	053632	000420				BR 4$		;
≥					1$:
≠CMP≡≡R1≡≡USEBUF≡≥	053634	020127	000002			CMP R1,#USEBUF	;USEBUF
≠BNE≡≥	053640	001003				BNE 2$
≠JSR≡≡PC≡≡DOUSBU≡≥	053642	004767	000146			JSR PC,DOUSBUF	;
≠BR≡≥	053646	000412				BR 4$		;
≥					2$:
≠CMP≡≡R1≡≡RELBUF≡≥	053650	020127	000003			CMP R1,#RELBUF	;RELBUF
≠BNE≡≥	053654	001003				BNE 3$
≠JSR≡≡PC≡≡DORLBU≡≥	053656	004767	000144			JSR PC,DORLBUF	;
≠BR≡≥	053662	000404				BR 4$		;
≥					3$:
≤HALERR≡≥						HALERR SRVMES 	;Illegal code
≠MOV≡≡SRVMES≡≡SP≡≥	053664	012746	053704			MOV #SRVMES,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	053670	004777	740116			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≥					
≠MOV≡≡R2≡≡R0≡≥	053674	010200			4$:	MOV R2,R0	;Release the note.
≠JSR≡≡PC≡≡RLFREE≡≥	053676	004767	754706			JSR PC,RLFREE	;
≠BR≡≡SERVER≡≥	053702	000742				BR SERVER	;One more river, there's one more river to cross.
≥					
≤ASCIE≡≥					SRVMES:	ASCIE </CAN'T UNDERSTAND NOTE FROM THE 10/>
≠.ASCIZ≡≥	053704	   103		
≥	053705	   101		
≥	053706	   116		
≥	053707	   047		
≥	053710	   124		
≥	053711	   040		
≥	053712	   125		
≥	053713	   116		
≥	053714	   104		
≥	053715	   105		
≥	053716	   122		
≥	053717	   123		
≥	053720	   124		
≥	053721	   101		
≥	053722	   116		
≥	053723	   104		
≥	053724	   040		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 225
	ALAID PAL[HAL,HE]	PAGE 4.2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	053725	   116		
≥	053726	   117		
≥	053727	   124		
≥	053730	   105		
≥	053731	   040		
≥	053732	   106		
≥	053733	   122		
≥	053734	   117		
≥	053735	   115		
≥	053736	   040		
≥	053737	   124		
≥	053740	   110		
≥	053741	   105		
≥	053742	   040		
≥	053743	   061		
≥	053744	   060		
≥	053745	   000		
≥					       .ASCIZ /CAN'T UNDERSTAND NOTE FROM THE 10/
≠.EVEN≡≥		053746			       .EVEN
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 226
	ALAID PAL[HAL,HE]	PAGE 5 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  DOGTBUF, DOUSBUF, DORLBUF
≥					
≥					DOGTBUF:
≠COMMEN≡≥				COMMENT ⊗ Called by SERVER.  The 10 wants us to allocate a buffer.
≥				R0 = LOC[note].  The size in bytes is in ARG1(R0).  We should respond
≥					with BUFALC <size> <adr>.  ⊗
≠MOV≡≡ARG1≡≡R0≡≡R0≡≥	053746	016000	000002			MOV ARG1(R0),R0	;R0 ← size argument
≠MOV≡≡R0≡≡SP≡≥	053752	010046				MOV R0,-(SP)	;Save size argument
≠JSR≡≡PC≡≡GTFREE≡≥	053754	004767	754266			JSR  PC,GTFREE	;Get the buffer out of free storage
≠MOV≡≡R0≡≡SP≡≥	053760	010046				MOV R0,-(SP)	;Save buffer address
≠MOV≡≡NOTSIZ≡≡R0≡≥	053762	012700	000003			MOV #NOTSIZ,R0	;
≠JSR≡≡PC≡≡GTFREE≡≥	053766	004767	754254			JSR PC,GTFREE	;R0 ← LOC[new note to send]
≠MOV≡≡BUFALC≡≡R0≡≥	053772	012710	000101			MOV #BUFALC,(R0)	;BUFALC
≠MOV≡≡SP≡≡ARG2≡≡R0≡≥	053776	012660	000004			MOV (SP)+,ARG2(R0) 	;  <adr>
≠MOV≡≡SP≡≡ARG1≡≡R0≡≥	054002	012660	000002			MOV (SP)+,ARG1(R0) 	;  <size>
≠JSR≡≡PC≡≡SNDNOT≡≥	054006	004767	777520			JSR PC,SNDNOTE	;Send the note off. (He will destroy it)
≠RTS≡≡PC≡≥	054012	000207				RTS PC		;Done
≥					
≥					DOUSBUF:
≠COMMEN≡≥				COMMENT ⊗ Called by SERVER.  R0 = LOC[note].  The buffer that starts
≥				at address ARG1(R0) is a message.  Look at it, act on it, and then
≥					recycle the message buffer.  ⊗
≠MOV≡≡ARG1≡≡R0≡≡R0≡≥	054014	016000	000002			MOV ARG1(R0),R0	;R0 ← LOC[message]
≠JSR≡≡PC≡≡TREATM≡≥	054020	004767	000106			JSR PC,TREATMESSAGE	;Treat it and release it
≠RTS≡≡PC≡≥	054024	000207				RTS PC		;Done
≥					
≥					DORLBUF:
≠COMMEN≡≥				COMMENT ⊗ Called by SERVER.  R0 = LOC[note].  The buffer that starts
≥					at ARG1(R0) has been used by the 10, and we may deallocate it now. ⊗
≠MOV≡≡ARG1≡≡R0≡≡R0≡≥	054026	016000	000002			MOV ARG1(R0),R0	;R0 ← LOC[expended message]
≠JSR≡≡PC≡≡RLFREE≡≥	054032	004767	754552			JSR PC,RLFREE	;
≠RTS≡≡PC≡≥	054036	000207				RTS PC		;Done
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 227
	ALAID PAL[HAL,HE]	PAGE 6 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  LINKQUEUE, UNLQUE, SAMEID
≥					
≥					LINKQUEUE:
≠COMMEN≡≥				COMMENT ⊗ There is a dummy queue at the start of the chain.  R1
≥				points to the queue header, and R0 is the one we wish to add in.  
≥				Exclusion should be on before this routine is called; it remains
≥					on afterwards.  ⊗
≠MOV≡≡QNEXT≡≡R1≡≡QNEXT≡≡R0≡≥	054040	016160	000000	000000		MOV QNEXT(R1),QNEXT(R0)
≠MOV≡≡R1≡≡QPREV≡≡R0≡≥	054046	010160	000002			MOV R1,QPREV(R0)
≠MOV≡≡R0≡≡QNEXT≡≡R1≡≥	054052	010061	000000			MOV R0,QNEXT(R1)
≠RTS≡≡PC≡≥	054056	000207				RTS PC
≥					
≥					UNLQUE:
≠COMMEN≡≥				COMMENT ⊗ R0 points to a queue node.  It is unlinked from its queue.
≥				R0 is left pointing at the same node.  Exclusion should be on before
≥					this routine is called; it will remain on afterwards.  ⊗
≠MOV≡≡QPREV≡≡R0≡≡R1≡≥	054060	016001	000002			MOV QPREV(R0),R1	;R1 ← prev(old)
≠MOV≡≡QNEXT≡≡R0≡≡QNEXT≡≡R1≡≥	054064	016061	000000	000000		MOV QNEXT(R0),QNEXT(R1)	;Transfer forward link.
≠MOV≡≡QNEXT≡≡R0≡≡R1≡≥	054072	016001	000000			MOV QNEXT(R0),R1	;R1 ← next(old)
≠BEQ≡≥	054076	001403				BEQ 1$			;If any
≠MOV≡≡QPREV≡≡R0≡≡QPREV≡≡R1≡≥	054100	016061	000002	000002		MOV QPREV(R0),QPREV(R1)	;Transfer backward link.
≠RTS≡≡PC≡≥	054106	000207			1$:	RTS PC			;Done.
≥					
≥					
≥					SAMEID:
≠COMMEN≡≥				COMMENT ⊗ R0 = header of queue.  R1 = ID to look for.  If there is a
≥				node in the queue with that ID, it is returned in R0.  Otherwise, R0
≥				← 0.  Exclusion should be on before this routine is called; it will
≥					remain on afterwards.  ⊗
≠MOV≡≡QNEXT≡≡R0≡≡R0≡≥	054110	016000	000000		1$:	MOV QNEXT(R0),R0	;R0 ← next (real) node in queue
≠BEQ≡≥	054114	001405				BEQ 2$			;If any.
≠CMP≡≡QID≡≡R0≡≡R1≡≥	054116	026001	000004			CMP QID(R0),R1		;Match the ID?
≠BNE≡≥	054122	001372				BNE 1$			;No.  Try next one.
≠JSR≡≡PC≡≡UNLQUE≡≥	054124	004767	777730			JSR PC,UNLQUE		;R0 ← same node, now unlinked.
≠RTS≡≡PC≡≥	054130	000207			2$:	RTS PC			;Done
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 228
	ALAID PAL[HAL,HE]	PAGE 7 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  TREATMESSAGE, GETOFS, DOERR, SNDANS
≥					
≥					TREATMESSAGE:
≠COMMEN≡≥				COMMENT ⊗ R0 = LOC[buffer from the 10].  Print out its contents and
≥					treat it.  ⊗
≠MOV≡≡R2≡≡SP≡≥	054132	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡R0≡≡R2≡≥	054134	010002				MOV R0,R2	;R2 ← LOC[buffer]
≥					
≥						;print the message
≠.IFZ≡≡DEBUG≡≥		000000			   .IFZ DEBUG
≤EVWAIT≡≥						EVWAIT CSLEVT	;
≤.ARG≡≥						  .ARG CSLEVT
≠.LIF≡≥						    .LIF NB CSLEVT
≠MOV≡≡CSLEVT≡≡SP≡≥	054136	016746	740254			      MOV CSLEVT,-(SP)
≥	054142	104010				104010
≥					   .ENDC
≠MOV≡≡CRLFX≡≡R0≡≥	054144	012700	014266			MOV #CRLFX,R0	;
≠JSR≡≡PC≡≡TYPSTR≡≥	054150	004767	737724			JSR PC,TYPSTR	;
≠MOV≡≡R2≡≡R0≡≥	054154	010200				MOV R2,R0	;
≠ADD≡≡MESBEG≡≡R0≡≥	054156	062700	000006			ADD #MESBEG,R0	;R0 ← LOC[start of message itself]
≠JSR≡≡PC≡≡TYPSTR≡≥	054162	004767	737712			JSR PC,TYPSTR	;Print it
≠.IFZ≡≡DEBUG≡≥		000000			   .IFZ DEBUG
≤EVSIG≡≥						EVSIG CSLEVT	;
≤.ARG≡≥						  .ARG CSLEVT
≠.LIF≡≥						    .LIF NB CSLEVT
≠MOV≡≡CSLEVT≡≡SP≡≥	054166	016746	740224			      MOV CSLEVT,-(SP)
≥	054172	104012				104012
≥					   .ENDC
≥					
≥						;see what kind of message it is
≠MOV≡≡R2≡≡R0≡≥	054174	010200				MOV R2,R0	;
≠MOV≡≡MESTYP≡≡R0≡≡R1≡≥	054176	016001	000002			MOV MESTYP(R0),R1	;R1 ← MESTYPE;
≠BIT≡≡ANSWER≡≡R1≡≥	054202	032701	000010			BIT #ANSWER,R1	;An  answer?
≠BEQ≡≥	054206	001430				BEQ 2$		;No
≥						
≥					
≥						;got a response.  See if anyone is waiting to hear it.
≠MOV≡≡MESID≡≡R0≡≡R1≡≥	054210	016001	000000			MOV MESID(R0),R1;R1 ← MESID
≤EVWAIT≡≥						EVWAIT ALDEVT	;Enter critical section
≤.ARG≡≥						  .ARG ALDEVT
≠.LIF≡≥						    .LIF NB ALDEVT
≠MOV≡≡ALDEVT≡≡SP≡≥	054214	016746	777222			      MOV ALDEVT,-(SP)
≥	054220	104010				104010
≠MOV≡≡WAITQ≡≡R0≡≥	054222	012700	053444			MOV #WAITQ,R0	;R0 ← head of wait.
≠JSR≡≡PC≡≡SAMEID≡≥	054226	004767	777656			JSR PC,SAMEID	;R0 ← queue node waiting for this MESID.
≤EVSIG≡≥						EVSIG ALDEVT	;End of critical section
≤.ARG≡≥						  .ARG ALDEVT
≠.LIF≡≥						    .LIF NB ALDEVT
≠MOV≡≡ALDEVT≡≡SP≡≥	054232	016746	777204			      MOV ALDEVT,-(SP)
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 229
	ALAID PAL[HAL,HE]	PAGE 7.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	054236	104012				104012
≠TST≡≡R0≡≥	054240	005700				TST R0		;Was there a waiting process?
≠BNE≡≥	054242	001004				BNE 1$		;Yes.
≤HALERR≡≥						HALERR TRTMMS	;None found.  A bug!
≠MOV≡≡TRTMMS≡≡SP≡≥	054244	012746	054300			MOV #TRTMMS,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	054250	004777	737536			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠MOV≡≡R2≡≡QBUF≡≡R0≡≥	054254	010260	000006		1$:	MOV R2,QBUF(R0)	;Give him his result.
≤EVSIG≡≥						EVSIG QEVT(R0)	;Give him his signal
≤.ARG≡≥						  .ARG QEVT(R0)
≠.LIF≡≥						    .LIF NB QEVT(R0)
≠MOV≡≡QEVT≡≡R0≡≡SP≡≥	054260	016046	000004			      MOV QEVT(R0),-(SP)
≥	054264	104012				104012
≠BR≡≥	054266	000402				BR 3$		;Prepare to leave
≥						
≥						;got a question.  Get someone to look at it.
≠JSR≡≡PC≡≡RLOOKP≡≥	054270	004767	001100		2$:	JSR PC,RLOOKP	;Start up a process to fulfill the request and
≥								;delete the message
≥					
≠MOV≡≡SP≡≡R2≡≥	054274	012602			3$:	MOV (SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	054276	000207				RTS PC		;
≥					
≤ASCIE≡≥					TRTMMS:	ASCIE </GOT UNEXPECTED ANSWER FROM THE 10./>
≠.ASCIZ≡≥	054300	   107		
≥	054301	   117		
≥	054302	   124		
≥	054303	   040		
≥	054304	   125		
≥	054305	   116		
≥	054306	   105		
≥	054307	   130		
≥	054310	   120		
≥	054311	   105		
≥	054312	   103		
≥	054313	   124		
≥	054314	   105		
≥	054315	   104		
≥	054316	   040		
≥	054317	   101		
≥	054320	   116		
≥	054321	   123		
≥	054322	   127		
≥	054323	   105		
≥	054324	   122		
≥	054325	   040		
≥	054326	   106		
≥	054327	   122		
≥	054330	   117		
≥	054331	   115		
≥	054332	   040		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 230
	ALAID PAL[HAL,HE]	PAGE 7.2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	054333	   124		
≥	054334	   110		
≥	054335	   105		
≥	054336	   040		
≥	054337	   061		
≥	054340	   060		
≥	054341	   056		
≥	054342	   000		
≥					       .ASCIZ /GOT UNEXPECTED ANSWER FROM THE 10./
≠.EVEN≡≥		054344			       .EVEN
≥					
≥					GETOFS:	
≠COMMEN≡≥				COMMENT ⊗ R2 = LOC[answer block].  We want to see (OFFSET n).  If we
≥				do, we put LOC[graph node for n] in GPHPTR(R2); otherwise R0 ← 0.  R2 is
≥					still LOC[answer block], but ARGPTR is properly updated. ⊗
≠MOV≡≡AGARG≡≡R2≡≡R0≡≥	054344	016200	000006			MOV AGARG(R2),R0;R0 ← LOC[argument string]
≠CMPB≡≡R0≡≥	054350	122027	000050			CMPB (R0)+,#'(	;A left paren?
≠BNE≡≥	054354	001034				BNE 1$		;No.  
≠JSR≡≡PC≡≡LOOKUP≡≥	054356	004767	000732			JSR PC,LOOKUP	;R0 ← next thing on arg, R1 ← OFSCOD, we hope.
≠CMP≡≡R1≡≡OFSCOD≡≥	054362	020127	000001			CMP R1,#OFSCOD	;Was it offset?
≠BNE≡≥	054366	001027				BNE 1$		;No.
≠JSR≡≡PC≡≡GETOCT≡≥	054370	004767	001316			JSR PC,GETOCT	;R0 ← after the arg, R1 ← octal number found.
≠MOV≡≡R0≡≡AGPTR≡≡R2≡≥	054374	010062	000010			MOV R0,AGPTR(R2);Save arg. ptr
≠MOV≡≡R1≡≡R0≡≥	054400	010100				MOV R1,R0	;R0 ← integer offset
≠MOV≡≡CURNAM≡≡R4≡≥	054402	016704	777032			MOV CURNAM,R4	;R4 ← LOC[ISB of active interpreter]
≠JSR≡≡PC≡≡GETARG≡≥	054406	004767	761650			JSR PC,GETARG	;R0 ← LOC[LOC[graph node]]
≠MOV≡≡R0≡≡GPHPTR≡≡R2≡≥	054412	011062	000014			MOV (R0),GPHPTR(R2)
≠BEQ≡≥	054416	001413				BEQ 1$		;If anyone home.  Else will return failure.
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	054420	016200	000010			MOV AGPTR(R2),R0;
≠JSR≡≡PC≡≡SKIPSP≡≥	054424	004767	001356			JSR PC,SKIPSP	;Skip spaces.
≠MOV≡≡R1≡≥	054430	012701	000051			MOV #'),R1	;
≠JSR≡≡PC≡≡SKIPOP≡≥	054434	004767	001360			JSR PC,SKIPOP	;Skip the ), if it is there.
≠MOV≡≡R0≡≡AGPTR≡≡R2≡≥	054440	010062	000010			MOV R0,AGPTR(R2);
≠RTS≡≡PC≡≥	054444	000207				RTS PC		;
≠CLR≡≡R0≡≥	054446	005000			1$:	CLR R0		;Failure return
≠RTS≡≡PC≡≥	054450	000207				RTS PC		;
≥					
≥					DOERR:	
≠COMMEN≡≥				COMMENT ⊗ There has been an error in parsing some command. R2 =
≥				LOC[answer block].  We will say "ERROR (message)".  R2 will be left
≥					with ANPTR fixed up.  ⊗
≠MOV≡≡ANPTR≡≡R2≡≡R0≡≥	054452	016200	000002			MOV ANPTR(R2),R0;R0 ← answer pointer
≠MOV≡≡ERRMES≡≡R1≡≥	054456	012701	055116			MOV #ERRMES,R1	;
≠JSR≡≡PC≡≡TACK≡≥	054462	004767	001310			JSR PC,TACK	;Tack on "ERROR "
≠MOV≡≡LPAREN≡≡R1≡≥	054466	012701	055100			MOV #LPAREN,R1	;
≠JSR≡≡PC≡≡TACK≡≥	054472	004767	001300			JSR PC,TACK	;Tack on " ( "
≠MOV≡≡AGBUF≡≡R2≡≡R1≡≥	054476	016201	000004			MOV AGBUF(R2),R1;
≠ADD≡≡MESBEG≡≡R1≡≥	054502	062701	000006			ADD #MESBEG,R1	;
≠JSR≡≡PC≡≡TACK≡≥	054506	004767	001264			JSR PC,TACK	;Tack on the original message
≠MOV≡≡RPAREN≡≡R1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 231
	ALAID PAL[HAL,HE]	PAGE 7.3 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	054512	012701	055104			MOV #RPAREN,R1	;
≠JSR≡≡PC≡≡TACK≡≥	054516	004767	001254			JSR PC,TACK	;Tack on " ) "
≠MOV≡≡R0≡≡ANPTR≡≡R2≡≥	054522	010062	000002			MOV R0,ANPTR(R2);
≠JMP≡≡SNDANS≡≥	054526	000167	000000			JMP SNDANS	;He will never return.
≥					
≥					SNDANS:
≠COMMEN≡≥				COMMENT ⊗ R2 = LOC[answer block]. ANPTR(R2) = end of the message.
≥				ANSBUF(R2) = front of the message.  Compute the message length, send
≥				the message out, reclaim the answer block, including the AGBUF, and
≥				then reclaim the interpreter stack, the PDB of this process and
≥					dismiss. ⊗
≥					
≥						;compute MESLTH
≠MOV≡≡ANPTR≡≡R2≡≡R1≡≥	054532	016201	000002			MOV ANPTR(R2),R1;R1 ← ans. ptr
≠MOV≡≡ANSBUF≡≡R2≡≡R0≡≥	054536	016200	000000			MOV ANSBUF(R2),R0	;R0 ← LOC[answer buffer]
≠SUB≡≡R0≡≡R1≡≥	054542	160001				SUB R0,R1	;R1 ← length in bytes of message
≠ASR≡≡R1≡≥	054544	006201				ASR R1		;in words
≠MOV≡≡R1≡≡MESLTH≡≡R0≡≥	054546	010160	000004			MOV R1,MESLTH(R0); MESLTH
≥					
≥						;send the result back.  R0 = LOC[message]
≠MOV≡≡NOTSIZ≡≡R0≡≥	054552	012700	000003			MOV #NOTSIZ,R0	;
≠JSR≡≡PC≡≡GTFREE≡≥	054556	004767	753464			JSR PC,GTFREE	;R0 ← LOC[new note to send]
≠MOV≡≡TAKBUF≡≡R0≡≥	054562	012710	000102			MOV #TAKBUF,(R0);TAKBUF
≠MOV≡≡SP≡≡R1≡≥	054566	011601				MOV (SP),R1	;R1 ← LOC[answer block]
≠MOV≡≡ANSBUF≡≡R2≡≡ARG1≡≡R0≡≥	054570	016260	000000	000002		MOV ANSBUF(R2),ARG1(R0)	;  <adr>
≠JSR≡≡PC≡≡SNDNOT≡≥	054576	004767	776730			JSR PC,SNDNOTE	;Send the note off. (He will destroy it)
≥					
≥						;reclaim answer block
≠MOV≡≡R2≡≡R0≡≥	054602	010200				MOV R2,R0	;Reclaim the argument message buffer
≠MOV≡≡AGBUF≡≡R0≡≡R0≡≥	054604	016000	000004			MOV AGBUF(R0),R0;
≠JSR≡≡PC≡≡RLFREE≡≥	054610	004767	753774			JSR PC,RLFREE	;
≠MOV≡≡R2≡≡R0≡≥	054614	010200				MOV R2,R0	;Reclaim the answer block itself
≠JSR≡≡PC≡≡RLFREE≡≥	054616	004767	753766			JSR PC,RLFREE	;
≥					
≥						;reclaim interpreter stack
≠MOV≡≡R3≡≡R0≡≥	054622	010300				MOV R3,R0	;
≠SUB≡≡INSTSZ≡≡R0≡≥	054624	162700	000020			SUB #INSTSZ,R0	;
≠JSR≡≡PC≡≡RLFREE≡≥	054630	004767	753754			JSR PC,RLFREE	;
≥					
≥						;reclaim Processor Desriptor Block
≠MOV≡≡R5≡≡R0≡≥	054634	010500				MOV R5,R0	;
≠JSR≡≡PC≡≡RLFREE≡≥	054636	004767	753746			JSR PC,RLFREE	;
≤DISMIS≡≥						DISMIS		;Gone!
≥	054642	104000				104000
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 232
	ALAID PAL[HAL,HE]	PAGE 8 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  MAKREQ, SNDREQ
≥					
≥					MAKREQ:	
≠COMMEN≡≥				COMMENT ⊗ Returns in R3 a pointer to a brand new request block, with
≥				REQBUF and REQPTR initialized to a new area for assembling a request.
≥					The REQBUF is initialized with MESTYP.  ⊗
≠MOV≡≡RQBSIZ≡≡R0≡≥	054644	012700	000005			MOV #RQBSIZ,R0	;Get a request block
≠JSR≡≡PC≡≡GTFREE≡≥	054650	004767	753372			JSR PC,GTFREE	;
≠MOV≡≡R0≡≡R3≡≥	054654	010003				MOV R0,R3	;R3 ← LOC[request block]
≠MOV≡≡BUFSIZ≡≡R0≡≥	054656	012700	000200			MOV #BUFSIZ,R0	;
≠JSR≡≡PC≡≡GTFREE≡≥	054662	004767	753360			JSR PC,GTFREE	;R0 ← LOC[request buffer]
≠MOV≡≡FROMEL≡≡REQUES≡≡MESTYP≡≡R0≡≥	054666	012760	000006	000002		MOV #FROMELF+REQUEST,MESTYP(R0)
≠MOV≡≡R0≡≡REQBUF≡≡R3≡≥	054674	010063	000000			MOV R0,REQBUF(R3)
≠ADD≡≡MESBEG≡≡R0≡≥	054700	062700	000006			ADD #MESBEG,R0	;
≠MOV≡≡R0≡≡REQPTR≡≡R3≡≥	054704	010063	000002			MOV R0,REQPTR(R3)
≠RTS≡≡PC≡≥	054710	000207				RTS PC		;
≥					
≥					SNDREQ:
≠COMMEN≡≥				COMMENT ⊗ R3 = LOC[request block]. REQPTR(R3) = end of the message.
≥				REQBUF(R3) = front of the message.  Compute the message length, send
≥				the message out, wait for a reply, and then put the response in
≥					REQRES(R3).  R3 is left pointing to the request block.  ⊗
≥					
≥						;compute MESLTH
≠MOV≡≡REQPTR≡≡R3≡≡R1≡≥	054712	016301	000002			MOV REQPTR(R3),R1	;R1 ← ans. ptr
≠MOV≡≡REQBUF≡≡R3≡≡R0≡≥	054716	016300	000000			MOV REQBUF(R3),R0	;R0 ← LOC[request buffer]
≠SUB≡≡R0≡≡R1≡≥	054722	160001				SUB R0,R1	;R1 ← length in bytes of message
≠ASR≡≡R1≡≥	054724	006201				ASR R1		;in words
≠MOV≡≡R1≡≡MESLTH≡≡R0≡≥	054726	010160	000004			MOV R1,MESLTH(R0); MESLTH
≥					
≠MOV≡≡REQBUF≡≡R3≡≡R0≡≥	054732	016300	000000			MOV REQBUF(R3),R0	;R0 ← LOC[message buffer]
≤EVMAK≡≥						EVMAK		;Get an event that will signal the response to the request.
≥	054736	104004				104004
≠MOV≡≡SP≡≡MESID≡≡R0≡≥	054740	011660	000000		 	MOV (SP),MESID(R0)	;That will be the MESID.
≠MOV≡≡SP≡≡REQEVT≡≡R3≡≥	054744	012663	000006			MOV (SP)+,REQEVT(R3)	;REQEVT
≥					
≠MOV≡≡QUELTH≡≡R0≡≥	054750	012700	000004			MOV #QUELTH,R0	;Enqueue ourselves for the response
≠JSR≡≡PC≡≡GTFREE≡≥	054754	004767	753266			JSR PC,GTFREE	;R0 ← LOC[queue node]
≠MOV≡≡R0≡≡REQQUE≡≡R3≡≥	054760	010063	000010			MOV R0,REQQUE(R3)	;REQQUE
≠MOV≡≡REQEVT≡≡R3≡≡QEVT≡≡R0≡≥	054764	016360	000006	000004		MOV REQEVT(R3),QEVT(R0)	;QEVT
≤EVWAIT≡≥						EVWAIT ALDEVT	;Enter critical region
≤.ARG≡≥						  .ARG ALDEVT
≠.LIF≡≥						    .LIF NB ALDEVT
≠MOV≡≡ALDEVT≡≡SP≡≥	054772	016746	776444			      MOV ALDEVT,-(SP)
≥	054776	104010				104010
≠MOV≡≡WAITQ≡≡R1≡≥	055000	012701	053444			MOV #WAITQ,R1	;
≠JSR≡≡PC≡≡LINKQU≡≥	055004	004767	777030			JSR PC,LINKQUEUE;
≤EVSIG≡≥						EVSIG ALDEVT	;Leave critical region
≤.ARG≡≥						  .ARG ALDEVT
≠.LIF≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 233
	ALAID PAL[HAL,HE]	PAGE 8.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥						    .LIF NB ALDEVT
≠MOV≡≡ALDEVT≡≡SP≡≥	055010	016746	776426			      MOV ALDEVT,-(SP)
≥	055014	104012				104012
≥					
≥						;send the request out.  R0 = LOC[message]
≠MOV≡≡NOTSIZ≡≡R0≡≥	055016	012700	000003			MOV #NOTSIZ,R0	;
≠JSR≡≡PC≡≡GTFREE≡≥	055022	004767	753220			JSR PC,GTFREE	;R0 ← LOC[new note to send]
≠MOV≡≡TAKBUF≡≡R0≡≥	055026	012710	000102			MOV #TAKBUF,(R0);TAKBUF
≠MOV≡≡REQBUF≡≡R3≡≡ARG1≡≡R0≡≥	055032	016360	000000	000002		MOV REQBUF(R3),ARG1(R0)	;  <adr>
≠JSR≡≡PC≡≡SNDNOT≡≥	055040	004767	776466			JSR PC,SNDNOTE	;Send the note off. (He will destroy it)
≤EVWAIT≡≥						EVWAIT REQEVT(R3)	;Wait for the event to happen
≤.ARG≡≥						  .ARG REQEVT(R3)
≠.LIF≡≥						    .LIF NB REQEVT(R3)
≠MOV≡≡REQEVT≡≡R3≡≡SP≡≥	055044	016346	000006			      MOV REQEVT(R3),-(SP)
≥	055050	104010				104010
≥					
≠COMMEN≡≥				        COMMENT ⊗ When the answer comes, the server will unlink the
≥				        queue for us.  We must destroy the event and reclaim the
≥					        queue node ourselves.  ⊗
≥					
≥						;the response has come, and the answer is in QBUF(REQQUE(R3))
≤EVKIL≡≥						EVKIL REQEVT(R3)	;
≤.ARG≡≥						  .ARG REQEVT(R3)
≠.LIF≡≥						    .LIF NB REQEVT(R3)
≠MOV≡≡REQEVT≡≡R3≡≡SP≡≥	055052	016346	000006			      MOV REQEVT(R3),-(SP)
≥	055056	104006				104006
≠MOV≡≡REQQUE≡≡R3≡≡R0≡≥	055060	016300	000010			MOV REQQUE(R3),R0	;
≠MOV≡≡QBUF≡≡R0≡≡REQRES≡≡R3≡≥	055064	016063	000006	000004		MOV QBUF(R0),REQRES(R3)	;REQRES
≠JSR≡≡PC≡≡RLFREE≡≥	055072	004767	753512			JSR PC,RLFREE		;Release the queue node
≠RTS≡≡PC≡≥	055076	000207				RTS PC		;
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 234
	ALAID PAL[HAL,HE]	PAGE 9 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  KTABLE, RTABLE, LOOKUP, RLOOKP, GETOCT, ascie messages
≥					
≠.ASCIZ≡≥	055100	   040		
≥	055101	   050		
≥	055102	   040		
≥	055103	   000		
≥					LPAREN:	.ASCIZ / ( /
≠.ASCIZ≡≥	055104	   040		
≥	055105	   051		
≥	055106	   040		
≥	055107	   000		
≥					RPAREN:	.ASCIZ / ) /
≠.ASCIZ≡≥	055110	   104		
≥	055111	   117		
≥	055112	   116		
≥	055113	   105		
≥	055114	   040		
≥	055115	   000		
≥					DONEMES:.ASCIZ /DONE /
≠.ASCIZ≡≥	055116	   105		
≥	055117	   122		
≥	055120	   122		
≥	055121	   117		
≥	055122	   122		
≥	055123	   040		
≥	055124	   000		
≥					ERRMES:	.ASCIZ /ERROR /
≠.ASCIZ≡≥	055125	   131		
≥	055126	   117		
≥	055127	   125		
≥	055130	   124		
≥	055131	   110		
≥	055132	   105		
≥	055133	   122		
≥	055134	   105		
≥	055135	   040		
≥	055136	   000		
≥					YTHMES:	.ASCIZ /YOUTHERE /
≠.EVEN≡≥		055140				.EVEN
≥					
≠.MACRO≡≤KWORD≠≥						.MACRO KWORD KNAME, KINFO
≥						II == .
≥						ASCIE /KNAME/
≥						. = II + 6	;Truncate to 6 characters
≥						KINFO		;Either code for this keyword, or service routine address
≥						.ENDM
≥						
≡OFSCOD≠≥		000001			OFSCOD == 1
≡SCACOD≠≥		000002			SCACOD == 2
≡VCTCOD≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 235
	ALAID PAL[HAL,HE]	PAGE 9.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥		000003			VCTCOD == 3
≡TRACOD≠≥		000004			TRACOD == 4
≡PLCCOD≠≥		000005			PLCCOD == 5
≥					
≥					KTABLE:	;List of keywords.
≤KWORD≡≥						KWORD <OFFSET>, OFSCOD
≡II≠≥		055140				II == .
≤ASCIE≡≥						ASCIE /OFFSET/
≠.ASCIZ≡≥	055140	   117		
≥	055141	   106		
≥	055142	   106		
≥	055143	   123		
≥	055144	   105		
≥	055145	   124		
≥	055146	   000		
≥					       .ASCIZ /OFFSET/
≠.EVEN≡≥		055150			       .EVEN
≡II≡≥		055146				. = II + 6	;Truncate to 6 characters
≡OFSCOD≡≡OFSCOD≡≥	055146	000001				 OFSCOD		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <SCALAR>, SCACOD
≡II≠≥		055150				II == .
≤ASCIE≡≥						ASCIE /SCALAR/
≠.ASCIZ≡≥	055150	   123		
≥	055151	   103		
≥	055152	   101		
≥	055153	   114		
≥	055154	   101		
≥	055155	   122		
≥	055156	   000		
≥					       .ASCIZ /SCALAR/
≠.EVEN≡≥		055160			       .EVEN
≡II≡≥		055156				. = II + 6	;Truncate to 6 characters
≡SCACOD≡≡SCACOD≡≥	055156	000002				 SCACOD		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <VECTOR>, VCTCOD
≡II≠≥		055160				II == .
≤ASCIE≡≥						ASCIE /VECTOR/
≠.ASCIZ≡≥	055160	   126		
≥	055161	   105		
≥	055162	   103		
≥	055163	   124		
≥	055164	   117		
≥	055165	   122		
≥	055166	   000		
≥					       .ASCIZ /VECTOR/
≠.EVEN≡≥		055170			       .EVEN
≡II≡≥		055166				. = II + 6	;Truncate to 6 characters
≡VCTCOD≡≡VCTCOD≡≥	055166	000003				 VCTCOD		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <TRANS >, TRACOD
≡II≠≥		055170				II == .
≤ASCIE≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 236
	ALAID PAL[HAL,HE]	PAGE 9.2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥						ASCIE /TRANS /
≠.ASCIZ≡≥	055170	   124		
≥	055171	   122		
≥	055172	   101		
≥	055173	   116		
≥	055174	   123		
≥	055175	   040		
≥	055176	   000		
≥					       .ASCIZ /TRANS /
≠.EVEN≡≥		055200			       .EVEN
≡II≡≥		055176				. = II + 6	;Truncate to 6 characters
≡TRACOD≡≡TRACOD≡≥	055176	000004				 TRACOD		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <PLACE >, PLCCOD
≡II≠≥		055200				II == .
≤ASCIE≡≥						ASCIE /PLACE /
≠.ASCIZ≡≥	055200	   120		
≥	055201	   114		
≥	055202	   101		
≥	055203	   103		
≥	055204	   105		
≥	055205	   040		
≥	055206	   000		
≥					       .ASCIZ /PLACE /
≠.EVEN≡≥		055210			       .EVEN
≡II≡≥		055206				. = II + 6	;Truncate to 6 characters
≡PLCCOD≡≡PLCCOD≡≥	055206	000005				 PLCCOD		;Either code for this keyword, or service routine address
≠.WORD≡≥	055210	000000			KTEND:	.WORD 0
≥					
≥					RTABLE:	;List of requests.
≤KWORD≡≥						KWORD <GETVAL>, DOGETVAL
≡II≠≥		055212				II == .
≤ASCIE≡≥						ASCIE /GETVAL/
≠.ASCIZ≡≥	055212	   107		
≥	055213	   105		
≥	055214	   124		
≥	055215	   126		
≥	055216	   101		
≥	055217	   114		
≥	055220	   000		
≥					       .ASCIZ /GETVAL/
≠.EVEN≡≥		055222			       .EVEN
≡II≡≥		055220				. = II + 6	;Truncate to 6 characters
≡DOGETV≡≡DOGETV≡≥	055220	056032				 DOGETVAL		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <SETVAL>, DOSETVAL
≡II≠≥		055222				II == .
≤ASCIE≡≥						ASCIE /SETVAL/
≠.ASCIZ≡≥	055222	   123		
≥	055223	   105		
≥	055224	   124		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 237
	ALAID PAL[HAL,HE]	PAGE 9.3 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	055225	   126		
≥	055226	   101		
≥	055227	   114		
≥	055230	   000		
≥					       .ASCIZ /SETVAL/
≠.EVEN≡≥		055232			       .EVEN
≡II≡≥		055230				. = II + 6	;Truncate to 6 characters
≡DOSETV≡≡DOSETV≡≥	055230	056130				 DOSETVAL		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <SIGNAL>, DOSIGNAL
≡II≠≥		055232				II == .
≤ASCIE≡≥						ASCIE /SIGNAL/
≠.ASCIZ≡≥	055232	   123		
≥	055233	   111		
≥	055234	   107		
≥	055235	   116		
≥	055236	   101		
≥	055237	   114		
≥	055240	   000		
≥					       .ASCIZ /SIGNAL/
≠.EVEN≡≥		055242			       .EVEN
≡II≡≥		055240				. = II + 6	;Truncate to 6 characters
≡DOSIGN≡≡DOSIGN≡≥	055240	056500				 DOSIGNAL		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <WAIT  >, DOWAIT
≡II≠≥		055242				II == .
≤ASCIE≡≥						ASCIE /WAIT  /
≠.ASCIZ≡≥	055242	   127		
≥	055243	   101		
≥	055244	   111		
≥	055245	   124		
≥	055246	   040		
≥	055247	   040		
≥	055250	   000		
≥					       .ASCIZ /WAIT  /
≠.EVEN≡≥		055252			       .EVEN
≡II≡≥		055250				. = II + 6	;Truncate to 6 characters
≡DOWAIT≡≡DOWAIT≡≥	055250	056560				 DOWAIT		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <SETNAM>, DOSETNAM
≡II≠≥		055252				II == .
≤ASCIE≡≥						ASCIE /SETNAM/
≠.ASCIZ≡≥	055252	   123		
≥	055253	   105		
≥	055254	   124		
≥	055255	   116		
≥	055256	   101		
≥	055257	   115		
≥	055260	   000		
≥					       .ASCIZ /SETNAM/
≠.EVEN≡≥		055262			       .EVEN
≡II≡≥		055260				. = II + 6	;Truncate to 6 characters
≡DOSETN≡≡DOSETN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 238
	ALAID PAL[HAL,HE]	PAGE 9.4 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	055260	056640				 DOSETNAM		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <START >, DOSTART
≡II≠≥		055262				II == .
≤ASCIE≡≥						ASCIE /START /
≠.ASCIZ≡≥	055262	   123		
≥	055263	   124		
≥	055264	   101		
≥	055265	   122		
≥	055266	   124		
≥	055267	   040		
≥	055270	   000		
≥					       .ASCIZ /START /
≠.EVEN≡≥		055272			       .EVEN
≡II≡≥		055270				. = II + 6	;Truncate to 6 characters
≡DOSTAR≡≡DOSTAR≡≥	055270	056766				 DOSTART		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <DDT   >, DODDT
≡II≠≥		055272				II == .
≤ASCIE≡≥						ASCIE /DDT   /
≠.ASCIZ≡≥	055272	   104		
≥	055273	   104		
≥	055274	   124		
≥	055275	   040		
≥	055276	   040		
≥	055277	   040		
≥	055300	   000		
≥					       .ASCIZ /DDT   /
≠.EVEN≡≥		055302			       .EVEN
≡II≡≥		055300				. = II + 6	;Truncate to 6 characters
≡DODDT≡≡DODDT≡≥	055300	057116				 DODDT		;Either code for this keyword, or service routine address
≤KWORD≡≥						KWORD <NOTICE>, DONOTICE
≡II≠≥		055302				II == .
≤ASCIE≡≥						ASCIE /NOTICE/
≠.ASCIZ≡≥	055302	   116		
≥	055303	   117		
≥	055304	   124		
≥	055305	   111		
≥	055306	   103		
≥	055307	   105		
≥	055310	   000		
≥					       .ASCIZ /NOTICE/
≠.EVEN≡≥		055312			       .EVEN
≡II≡≥		055310				. = II + 6	;Truncate to 6 characters
≡DONOTI≡≡DONOTI≡≥	055310	057256				 DONOTICE		;Either code for this keyword, or service routine address
≠.WORD≡≥	055312	000000			RTEND:	.WORD 0
≥					
≠COMMEN≡≥				COMMENT ⊗ R0 = LOC[string]. Find which keyword heads the string,
≥				using a disgusting linear search, and return R1 ← 0 if no keyword
≥				found, otherwise R1 ← code for that keyword.  R0 ← next entry on
≥					string. ⊗
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 239
	ALAID PAL[HAL,HE]	PAGE 9.5 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					
≥					LOOKUP:	
≠MOV≡≡R2≡≡SP≡≥	055314	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡KTABLE≡≡R1≡≥	055316	012701	055140			MOV #KTABLE,R1	;R1 ← LOC[current try in KTABLE]
≠MOV≡≡R2≡≥	055322	012702	000006		1$:	MOV #6,R2	;R2 ← count of how many characters to match.
≠CMPB≡≡R0≡≡R1≡≥	055326	122021			2$:	CMPB (R0)+,(R1)+;Match the next letter?
≠BEQ≡≥	055330	001411				BEQ 4$		;Yes
≠ADD≡≡R2≡≡R0≡≥	055332	060200			3$:	ADD R2,R0	;
≠SUB≡≡R0≡≥	055334	162700	000007			SUB #7,R0	;R0 ← start of given string.
≠ADD≡≡R2≡≡R1≡≥	055340	060201				ADD R2,R1	;R1 ← end of test string
≠TSTB≡≡R1≡≥	055342	105721				TSTB (R1)+	;R1 ← start of next test string
≠CMP≡≡R1≡≡KTEND≡≥	055344	020127	055210			CMP R1,#KTEND	;Off the end?
≠BLT≡≥	055350	002764				BLT 1$		;No.
≠BR≡≥	055352	000406				BR 6$		;Yes.
≠SOB≡≡R2≡≥	055354	077214			4$:	SOB R2,2$	;Try the next, if any.
≥						;found a match.  R1 = LOC[KINFO]
≠JSR≡≡PC≡≡SKIPSP≡≥	055356	004767	000424			JSR PC,SKIPSP 	;Skip spaces (does not hurt R1)
≠MOV≡≡R1≡≡R1≡≥	055362	011101				MOV (R1),R1	;R1 ← KINFO
≠MOV≡≡SP≡≡R2≡≥	055364	012602			5$:	MOV (SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	055366	000207				RTS PC		;Done
≠CLR≡≡R1≡≥	055370	005001			6$:	CLR R1		;Did not find anything
≠BR≡≥	055372	000774				BR 5$		;
≥					
≠COMMEN≡≥				COMMENT ⊗ R0 = LOC[message buffer request]. Find which request word
≥				heads the string, using a disgusting linear search, and start a
≥				process to handle the request.  He will see to the deletion of the
≥					message buffer.  ⊗
≥					
≥					RLOOKP:	
≠MOV≡≡R2≡≡SP≡≥	055374	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡R0≡≡SP≡≥	055376	010046				MOV R0,-(SP)	;Save LOC[message buffer request]
≠ADD≡≡MESBEG≡≡R0≡≥	055400	062700	000006			ADD #MESBEG,R0	;R0 ← LOC[request string]
≠MOV≡≡RTABLE≡≡R1≡≥	055404	012701	055212			MOV #RTABLE,R1	;R1 ← LOC[current try in KTABLE]
≠MOV≡≡R2≡≥	055410	012702	000006		1$:	MOV #6,R2	;R2 ← count of how many characters to match.
≠CMPB≡≡R0≡≡R1≡≥	055414	122021			2$:	CMPB (R0)+,(R1)+;Match the next letter?
≠BEQ≡≥	055416	001413				BEQ 4$		;Yes
≠ADD≡≡R2≡≡R0≡≥	055420	060200			3$:	ADD R2,R0	;
≠SUB≡≡R0≡≥	055422	162700	000007			SUB #7,R0	;R0 ← start of given string.
≠ADD≡≡R2≡≡R1≡≥	055426	060201				ADD R2,R1	;R1 ← end of test string
≠TSTB≡≡R1≡≥	055430	105721				TSTB (R1)+	;R1 ← start of next test string
≠CMP≡≡R1≡≡RTEND≡≥	055432	020127	055312			CMP R1,#RTEND	;Off the end?
≠BLT≡≥	055436	002764				BLT 1$		;No.
≠MOV≡≡DOERR≡≡R2≡≥	055440	012702	054452			MOV #DOERR,R2	;So what we will do is handle the error.
≠BR≡≥	055444	000402				BR 5$
≠SOB≡≡R2≡≥	055446	077216			4$:	SOB R2,2$	;Try the next, if any.
≥						;found a match.  R1 = LOC[KINFO]
≠MOV≡≡R1≡≡R2≡≥	055450	011102				MOV (R1),R2	;R2 ← KINFO = address of service routine
≠JSR≡≡PC≡≡SKIPSP≡≥	055452	004767	000330		5$:	JSR PC,SKIPSP 	;Skip spaces
≠MOV≡≡R0≡≡SP≡≥	055456	010046				MOV R0,-(SP)	;Save AGPTR
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 240
	ALAID PAL[HAL,HE]	PAGE 9.6 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					
≥						;build the answer block
≠MOV≡≡BUFSIZ≡≡R0≡≥	055460	012700	000200			MOV #BUFSIZ,R0	
≠JSR≡≡PC≡≡GTFREE≡≥	055464	004767	752556			JSR PC,GTFREE	;R0 ← LOC[answer buffer]
≠MOV≡≡SP≡≡R1≡≥	055470	016601	000002			MOV 2(SP),R1	;R1 ← AGBUF
≠MOV≡≡MESID≡≡R1≡≡MESID≡≡R0≡≥	055474	016160	000000	000000		MOV MESID(R1),MESID(R0)	;Transfer the MESID to answer from request.
≠MOV≡≡FROMEL≡≡ANSWER≡≡MESTYP≡≡R0≡≥	055502	012760	000012	000002		MOV #FROMELF+ANSWER,MESTYP(R0)	;MESTYP
≠MOV≡≡R0≡≡SP≡≥	055510	010046				MOV R0,-(SP)	;Save ANSBUF
≠MOV≡≡ABKSIZ≡≡R0≡≥	055512	012700	000007			MOV #ABKSIZ,R0	;Get an answer block
≠JSR≡≡PC≡≡GTFREE≡≥	055516	004767	752524			JSR PC,GTFREE	;R0 ← LOC[answer block]
≠MOV≡≡SP≡≡R1≡≥	055522	012601				MOV (SP)+,R1	;R1 ← ANSBUF
≠MOV≡≡R1≡≡ANSBUF≡≡R0≡≥	055524	010160	000000			MOV R1,ANSBUF(R0)
≠ADD≡≡MESBEG≡≡R1≡≥	055530	062701	000006			ADD #MESBEG,R1	;
≠MOV≡≡R1≡≡ANPTR≡≡R0≡≥	055534	010160	000002			MOV R1,ANPTR(R0);
≠MOV≡≡SP≡≡AGARG≡≡R0≡≥	055540	011660	000006			MOV (SP),AGARG(R0)
≠MOV≡≡SP≡≡AGPTR≡≡R0≡≥	055544	012660	000010			MOV (SP)+,AGPTR(R0)
≠MOV≡≡SP≡≡AGBUF≡≡R0≡≥	055550	012660	000004			MOV (SP)+,AGBUF(R0)
≠MOV≡≡R0≡≡SP≡≥	055554	010046				MOV R0,-(SP)	;Save LOC[answer block]
≥					
≥						;set up a new process with R2 ← LOC[answer block] to fulfil request.
≡INSTSZ≠≥		000020				INSTSZ == 20	;Size of an interpreter stack
≠MOV≡≡INSTSZ≡≡R0≡≥	055556	012700	000020			MOV #INSTSZ,R0	;R3 stack space
≠JSR≡≡PC≡≡GTFREE≡≥	055562	004767	752460			JSR PC,GTFREE	;
≠ADD≡≡INSTSZ≡≡R0≡≥	055566	062700	000020			ADD #INSTSZ,R0	;to end of space
≠MOV≡≡R0≡≡SP≡≥	055572	010046				MOV R0,-(SP)	;Save stack space
≠MOV≡≡R0≡≥	055574	012700	000210			MOV #210,R0	;Room for process descriptor
≠JSR≡≡PC≡≡GTFREE≡≥	055600	004767	752442			JSR PC,GTFREE	;R0 ← LOC[new process descriptor]
≠MOV≡≡UFPUSE≡≡UGRSAV≡≡PDBSTA≡≡R0≡≥	055604	012760	104000	000000		MOV #UFPUSE+UGRSAV,PDBSTA(R0);Use floating point, use saved registers.
≠MOV≡≡UPDLEN≡≡R0≡≥	055612	012760	000420	000002		MOV #420,UPDLEN(R0)	;Length of PDB
≠MOV≡≡R0≡≡R1≡≥	055620	010001				MOV R0,R1	;
≠ADD≡≡R1≡≥	055622	062701	000420			ADD #420,R1	;
≠MOV≡≡R1≡≡PDBSP≡≡R0≡≥	055626	010160	000014			MOV R1,PDBSP(R0)	;Store away the new stack pointer (reg 6)
≠MOV≡≡SP≡≡PDBR3≡≡R0≡≥	055632	012660	000034			MOV (SP)+,PDBR3(R0)	;Store away the R3 stack pointer.
≠MOV≡≡SP≡≡PDBR2≡≡R0≡≥	055636	012660	000032			MOV (SP)+,PDBR2(R0)	;Store away the R2 = LOC[answer block]
≠MOV≡≡CURNAM≡≡PDBR4≡≡R0≡≥	055642	016760	775572	000036		MOV CURNAM,PDBR4(R0)	;Start out on the current ISB
≠MOV≡≡R0≡≡PDBR5≡≡R0≡≥	055650	010060	000040			MOV R0,PDBR5(R0);Store away the R5 = PDB address.
≠MOV≡≡UIMAP≡≡R0≡≥	055654	012760	000376	000022		MOV #376,UIMAP(R0)	;Map instruction space
≠MOV≡≡UDMAP≡≡R0≡≥	055662	012760	000576	000024	        MOV #576,UDMAP(R0)  	;Sets data space to map 1, which puts phys 160000
≠ADD≡≡PDBSTA≡≡R0≡≥	055670	062700	000000			ADD #PDBSTA,R0	;Move R0 to the middle of the process descriptor
≤FORK≡≥						FORK R0,R2,#2	;Cause the new process to be started
≤.ARG≡≥						  .ARG #2
≠.LIF≡≥						    .LIF NB #2
≠MOV≡≡SP≡≥	055674	012746	000002			      MOV #2,-(SP)
≤.ARG≡≥						  .ARG R2
≠.LIF≡≥						    .LIF NB R2
≠MOV≡≡R2≡≡SP≡≥	055700	010246				      MOV R2,-(SP)
≤.ARG≡≥						  .ARG R0
≠.LIF≡≥						    .LIF NB R0
≠MOV≡≡R0≡≡SP≡≥	055702	010046				      MOV R0,-(SP)
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 241
	ALAID PAL[HAL,HE]	PAGE 9.7 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	055704	104002				104002
≥					
≠MOV≡≡SP≡≡R2≡≥	055706	012602			6$:	MOV (SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	055710	000207				RTS PC		;Done
≥					
≥					GETOCT:
≠COMMEN≡≥				COMMENT ⊗ R0 = string pointer.  Finds an octal number, skipping
≥				spaces to do so, and places its value in R1.  Leaves R0 at end of
≥					spaces following the string. ⊗
≠MOV≡≡R2≡≡SP≡≥	055712	010246				MOV R2,-(SP)	;Save R2
≠CLR≡≡R1≡≥	055714	005001				CLR R1		;R1 is the eventual result
≠JSR≡≡PC≡≡SKIPSP≡≥	055716	004767	000064			JSR PC,SKIPSP	;Skip leading spaces
≠MOVB≡≡R0≡≡R2≡≥	055722	112002			1$:	MOVB (R0)+,R2	;R2 ← Character
≠CMP≡≡R2≡≥	055724	022702	000060			CMP #'0,R2	;Too small?
≠BGT≡≥	055730	003003				BGT 2$		;yes
≠CMP≡≡R2≡≥	055732	022702	000067			CMP #'7,R2	;Too large?
≠BGE≡≥	055736	002005				BGE 3$		;no
≠TSTB≡≡R0≡≥	055740	105740			2$:	TSTB -(R0)	;Move back one place
≠JSR≡≡PC≡≡SKIPSP≡≥	055742	004767	000040			JSR PC,SKIPSP	;skip trailing spaces
≠MOV≡≡SP≡≡R2≡≥	055746	012602				MOV (SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	055750	000207				RTS PC		;Done
≠MOV≡≡R2≡≡SP≡≥	055752	010246			3$:	MOV R2,-(SP)	;Save the character
≠ASH≡≡R1≡≥	055754	072127	000003			ASH #3,R1	;Compute new result
≠BIC≡≡SP≡≥	055760	042716	000060			BIC #60,(SP)	;
≠ADD≡≡SP≡≡R1≡≥	055764	062601				ADD (SP)+,R1	;
≠BR≡≥	055766	000755				BR  1$		;And repeat
≡TACK≡≡TACK≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 242
	ALAID PAL[HAL,HE]	PAGE 10 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	055770	055776		
≡SKIPSP≡≥	055772	056006		
≡SKIPOP≡≥	055774	056020			   TACK, SKIPSP, SKIPOPT
≥					
≥					TACK:
≠COMMEN≡≥				COMMENT ⊗ R1 = LOC[ascie string to tack on], R0 = LOC[where to put
≥					it].  Returns R0 ← next location available in destination string.  ⊗
≠MOVB≡≡R1≡≡R0≡≥	055776	112120				MOVB (R1)+,(R0)+;Copy a byte
≠BNE≡≡TACK≡≥	056000	001376				BNE TACK	;Repeat while necessary
≠DEC≡≡R0≡≥	056002	005300				DEC R0		;Go back past the null
≠RTS≡≡PC≡≥	056004	000207				RTS PC		;Done
≥					
≥					SKIPSP:
≠COMMEN≡≥				COMMENT ⊗ R0 = LOC[string].  Skip past any spaces, returning R0 ← LOC[next
≥					non-space element of the string.  Leaves R1 unchanged.  ⊗
≠CMPB≡≡R0≡≥	056006	122027	000040			CMPB (R0)+,#' 	;
≠BEQ≡≡SKIPSP≡≥	056012	001775				BEQ SKIPSP	;
≠DEC≡≡R0≡≥	056014	005300				DEC R0		;Go back past the non-space
≠RTS≡≡PC≡≥	056016	000207				RTS PC		;
≥					
≥					SKIPOPT:
≠COMMEN≡≥				COMMENT ⊗ R0 = LOC[string].  Skip past the character in R1, if it is
≥					the next character, and in any case, skip past any spaces.  ⊗
≠CMPB≡≡R0≡≡R1≡≥	056020	121001				CMPB (R0),R1	;The optional character?
≠BNE≡≥	056022	001001				BNE 1$		;No
≠TSTB≡≡R0≡≥	056024	105720				TSTB (R0)+	;Yes.  Skip it.
≠JMP≡≡SKIPSP≡≥	056026	000167	777754		1$:	JMP SKIPSP	;Skip over spaces, and let SKIPSP return.
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 243
	ALAID PAL[HAL,HE]	PAGE 11 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  DOGETVAL, DOSETVAL
≥					
≠COMMEN≡≥				COMMENT ⊗ All service routines are instantiated as processes, where
≥				R2 points at an answer block, with ANPTR, ANSBUF, AGBUF, AGPTR, AGARG
≥				all set up.  The ANSBUF already has MESID and MESTYP set.  R3 points
≥				at an interpreter stack, if it should be needed, and R5 points at the
≥				PDB, for reclamation purposes.  Service routines dismiss when they
≥					are finished, having destroyed their PDB. ⊗
≥					
≥					DOGETVAL:	;Service routine
≠COMMEN≡≥				COMMENT ⊗ Currently accepted argument string is: (OFFSET n).  The
≥				OFFSET construct will cause that variable in the current interpreter
≥				to have its value produced.  The answer is of the form "ISVAL arg
≥				val", unless something goes wrong, in which case the answer will be
≥					"ERROR (GETVAL arg)".  ⊗
≥					
≥						;scan the arguments
≠JSR≡≡PC≡≡GETOFS≡≥	056032	004767	776306			JSR PC,GETOFS	;GPHPTR(R2) ← LOC[graph node for offset]
≠TST≡≡R0≡≥	056036	005700				TST R0		;or was there an error?
≠BEQ≡≥	056040	001427				BEQ 1$		;oops.
≤CALL≡≥						CALL GETVAL,<GPHPTR(R2)>;R0 ← LOC[value]
≠MOV≡≡RF≡≡SP≡≥	056042	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB GPHPTR(R2)
≠.IRP≡≥						       .IRP II,<GPHPTR(R2)>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡GPHPTR≡≡R2≡≡SP≡≥	056044	016246	000014				MOV	GPHPTR(R2),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	056050	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	056054	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡GETVAL≡≥	056056	004767	002714			JSR	PC,GETVAL		;Call the routine
≠MOV≡≡R0≡≡VALPTR≡≡R2≡≥	056062	010062	000012			MOV R0,VALPTR(R2)	;
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	056066	016200	000010			MOV AGPTR(R2),R0;
≠TSTB≡≡R0≡≥	056072	105710				TSTB (R0)	;At the end?
≠BNE≡≥	056074	001011				BNE 1$		;No.  extra arguments.
≥					
≥						;prepare the answer. Note that TACK and TACKVAL take a string pointer
≥						; in R0 and leave it right afterwords.
≠MOV≡≡ANPTR≡≡R2≡≡R0≡≥	056076	016200	000002			MOV ANPTR(R2),R0	;R0 ← answer pointer
≠MOV≡≡VALPTR≡≡R2≡≡R1≡≥	056102	016201	000012			MOV VALPTR(R2),R1	;R0 ← LOC[value]
≠JSR≡≡PC≡≡TACKVA≡≥	056106	004767	772152			JSR PC,TACKVAL	;Tack it on
≠MOV≡≡R0≡≡ANPTR≡≡R2≡≥	056112	010062	000002			MOV R0,ANPTR(R2);
≠BR≡≥	056116	000402				BR 2$		;Ready to send it back
≥					
≥						;In this case, cannot make sense of the argument.
≠JMP≡≡DOERR≡≥	056120	000167	776326		1$:	JMP DOERR	;
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 244
	ALAID PAL[HAL,HE]	PAGE 11.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					
≥					2$:	;ANPTR(R2) = end of the message.  ANSBUF(R2) = front of the message
≠JMP≡≡SNDANS≡≥	056124	000167	776402			JMP SNDANS	;Send it winging on its way. Reclaim the answer block.
≥								;Reclaim the PDB.  Dismiss.
≥					
≥					DOSETVAL:
≠COMMEN≡≥				COMMENT ⊗ Currently accepted argument string is: (OFFSET n) (SCALAR
≥				n.n), (VECTOR n n n), or (TRANS n n ... n).  The variable specified
≥				by the first argument has its value changed to the value given by the
≥				second argument.  The answer is of the form "DONE", unless something
≥				goes wrong, in which case the answer will be "ERROR (SETVAL args)".
≥					⊗
≥					
≥						;scan the arguments
≠JSR≡≡PC≡≡GETOFS≡≥	056130	004767	776210			JSR PC,GETOFS	;GPHPTR(R2) ← LOC[graph node for offset]
≠TST≡≡R0≡≥	056134	005700				TST R0		;or was there an error?
≠BEQ≡≥	056136	001554				BEQ 7$		;oops.
≠CMPB≡≡R0≡≥	056140	122027	000050			CMPB (R0)+,#'(	;A left paren?
≠BNE≡≥	056144	001151				BNE 7$		;No.  
≠JSR≡≡PC≡≡LOOKUP≡≥	056146	004767	777142			JSR PC,LOOKUP	;R0 ← next thing on arg, R1 ← SCLCOD, we hope.
≠CMP≡≡R1≡≡SCACOD≡≥	056152	020127	000002			CMP R1,#SCACOD	;Was it SCALAR?
≠BNE≡≥	056156	001014				BNE 1$		;No.
≠JSR≡≡PC≡≡RELSCN≡≥	056160	004767	773152			JSR PC,RELSCN	;R0 ← after the arg, R1 ← 0 <=> number, AC0 ← float rep.
≠MOV≡≡R0≡≡AGPTR≡≡R2≡≥	056164	010062	000010			MOV R0,AGPTR(R2);Save arg. ptr
≠TST≡≡R1≡≥	056170	005701				TST R1		;Number?
≠BNE≡≥	056172	001136				BNE 7$		;No
≠JSR≡≡PC≡≡GETSCA≡≥	056174	004767	760224			JSR PC,GETSCA	;R0 ← -(R3) ← LOC[scalar cell]
≠MOV≡≡R3≡≡VALPTR≡≡R2≡≥	056200	012362	000012			MOV (R3)+,VALPTR(R2)
≠STF≡≡AC0≡≡R0≡≥	056204	174010				STF AC0,(R0)	;Put 'er in.
≠BR≡≥	056206	000467				BR 5$
≥					
≠CMP≡≡R1≡≡VCTCOD≡≥	056210	020127	000003		1$:	CMP R1,#VCTCOD	;Was it VECTOR?
≠BNE≡≥	056214	001032				BNE 3$		;No.
≠MOV≡≡R0≡≡AGPTR≡≡R2≡≥	056216	010062	000010			MOV R0,AGPTR(R2);Save arg. ptr
≠JSR≡≡PC≡≡GETVEC≡≥	056222	004767	760220			JSR PC,GETVEC	;R0 ← -(R3) ← LOC[trans cell]
≠MOV≡≡R3≡≡VALPTR≡≡R2≡≥	056226	012362	000012			MOV (R3)+,VALPTR(R2)
≠MOV≡≡R3≡≡SP≡≥	056232	010346				MOV R3,-(SP)	;Save R3
≠MOV≡≡R4≡≡SP≡≥	056234	010446				MOV R4,-(SP)	;Save R4
≠MOV≡≡R0≡≡R4≡≥	056236	010004				MOV R0,R4	;R4 ← LOC[vector cell]
≠MOV≡≡R3≡≥	056240	012703	000003			MOV #3,R3	;R3 ← count of how many places in VECTOR to fill.
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	056244	016200	000010			MOV AGPTR(R2),R0;
≠JSR≡≡PC≡≡RELSCN≡≥	056250	004767	773062		2$:	JSR PC,RELSCN	;R0 ← after the arg, R1 ← 0 <=> number, AC0 ← float rep.
≠TST≡≡R1≡≥	056254	005701				TST R1		;Number?
≠BNE≡≥	056256	001102				BNE 6$		;No
≠STF≡≡AC0≡≡R4≡≥	056260	174024				STF AC0,(R4)+	;Put 'er in.
≠SOB≡≡R3≡≥	056262	077306				SOB R3,2$	;Repeat
≠MOV≡≡ONE≡≡R4≡≥	056264	016724	773042			MOV ONE,(R4)+	;Set weight to one
≠MOV≡≡R0≡≡AGPTR≡≡R2≡≥	056270	010062	000010			MOV R0,AGPTR(R2);
≠MOV≡≡SP≡≡R4≡≥	056274	012604				MOV (SP)+,R4	;Restore R4
≠MOV≡≡SP≡≡R3≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 245
	ALAID PAL[HAL,HE]	PAGE 11.2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	056276	012603				MOV (SP)+,R3	;Restore R3
≠BR≡≥	056300	000432				BR 5$
≥					
≠CMP≡≡R1≡≡TRACOD≡≥	056302	020127	000004		3$:	CMP R1,#TRACOD	;Was it TRANS?
≠BNE≡≥	056306	001070				BNE 7$		;No.
≠MOV≡≡R0≡≡AGPTR≡≡R2≡≥	056310	010062	000010			MOV R0,AGPTR(R2);Save arg. ptr
≠JSR≡≡PC≡≡GETTRN≡≥	056314	004767	760150			JSR PC,GETTRN	;R0 ← -(R3) ← LOC[trans cell]
≠MOV≡≡R3≡≡VALPTR≡≡R2≡≥	056320	012362	000012			MOV (R3)+,VALPTR(R2)
≠MOV≡≡R3≡≡SP≡≥	056324	010346				MOV R3,-(SP)	;Save R3
≠MOV≡≡R4≡≡SP≡≥	056326	010446				MOV R4,-(SP)	;Save R4
≠MOV≡≡R0≡≡R4≡≥	056330	010004				MOV R0,R4	;R4 ← LOC[trans cell]
≠MOV≡≡R3≡≥	056332	012703	000014			MOV #14,R3	;R3 ← count of how many places in TRANS to fill.
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	056336	016200	000010			MOV AGPTR(R2),R0;
≠JSR≡≡PC≡≡RELSCN≡≥	056342	004767	772770		4$:	JSR PC,RELSCN	;R0 ← after the arg, R1 ← 0 <=> number, AC0 ← float rep.
≠TST≡≡R1≡≥	056346	005701				TST R1		;Number?
≠BNE≡≥	056350	001045				BNE 6$		;No
≠STF≡≡AC0≡≡R4≡≥	056352	174024				STF AC0,(R4)+	;Put 'er in.
≠SOB≡≡R3≡≥	056354	077306				SOB R3,4$	;Repeat
≠MOV≡≡R0≡≡AGPTR≡≡R2≡≥	056356	010062	000010			MOV R0,AGPTR(R2);
≠MOV≡≡SP≡≡R4≡≥	056362	012604				MOV (SP)+,R4	;Restore R4
≠MOV≡≡SP≡≡R3≡≥	056364	012603				MOV (SP)+,R3	;Restore R3
≥					
≠MOV≡≡GPHPTR≡≡R2≡≡R1≡≥	056366	016201	000014		5$:	MOV GPHPTR(R2),R1	;R1 ← LOC[graph node]
≤CALL≡≥						CALL CHANGE,<GPHPTR(R2),VALPTR(R2)>
≠MOV≡≡RF≡≡SP≡≥	056372	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB GPHPTR(R2),VALPTR(R2)
≠.IRP≡≥						       .IRP II,<GPHPTR(R2),VALPTR(R2)>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡GPHPTR≡≡R2≡≡SP≡≥	056374	016246	000014				MOV	GPHPTR(R2),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡VALPTR≡≡R2≡≡SP≡≥	056400	016246	000012				MOV	VALPTR(R2),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	056404	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	056410	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡CHANGE≡≥	056412	004767	002062			JSR	PC,CHANGE		;Call the routine
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	056416	016200	000010			MOV AGPTR(R2),R0;R0 ← arg. ptr.
≠JSR≡≡PC≡≡SKIPSP≡≥	056422	004767	777360			JSR PC,SKIPSP	;Scan past spaces
≠MOVB≡≡R1≡≥	056426	112701	000051			MOVB #'),R1	;
≠JSR≡≡PC≡≡SKIPOP≡≥	056432	004767	777362			JSR PC,SKIPOPT	;Skip right paren, if any, plus spaces
≠TSTB≡≡R0≡≥	056436	105710				TSTB (R0)	;At the end?
≠BNE≡≥	056440	001013				BNE 7$		;No.  extra arguments.
≥					
≥						;prepare the answer. Note that TACK and TACKVAL take a string pointer
≥						; in R0 and leave it right afterwords.
≠MOV≡≡ANPTR≡≡R2≡≡R0≡≥	056442	016200	000002			MOV ANPTR(R2),R0	;R0 ← answer pointer
≠MOV≡≡DONEME≡≡R1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 246
	ALAID PAL[HAL,HE]	PAGE 11.3 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	056446	012701	055110			MOV #DONEMES,R1	;
≠JSR≡≡PC≡≡TACK≡≥	056452	004767	777320			JSR PC,TACK	;Tack on "DONE "
≠MOV≡≡R0≡≡ANPTR≡≡R2≡≥	056456	010062	000002			MOV R0,ANPTR(R2);
≠BR≡≥	056462	000404				BR 8$		;Ready to send it back
≥					
≥						;in this case, trying to scan a number and failed.
≠MOV≡≡SP≡≡R4≡≥	056464	012604			6$:	MOV (SP)+,R4	;Restore R4
≠MOV≡≡SP≡≡R3≡≥	056466	012603				MOV (SP)+,R3	;Restore R3
≥					
≥						;In this case, cannot make sense of the argument.
≠JMP≡≡DOERR≡≥	056470	000167	775756		7$:	JMP DOERR	;
≥					
≥					8$:	;ANPTR(R2) = end of the message.  ANSBUF(R2) = front of the message
≠JMP≡≡SNDANS≡≥	056474	000167	776032			JMP SNDANS	;Send it winging on its way. Reclaim the answer block.
≥								;Reclaim the PDB.  Dismiss.
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 247
	ALAID PAL[HAL,HE]	PAGE 12 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  DOWAIT, DOSIGNAL;
≥					
≥					DOSIGNAL:	;Service routine
≠COMMEN≡≥				COMMENT ⊗ Currently accepted argument string is: (OFFSET n).  The
≥				OFFSET construct will cause that variable in the current interpreter
≥				to be signaled.  The answer is of the form "DONE", unless something
≥					goes wrong, in which case the answer will be "ERROR (SIGNAL arg)".  ⊗
≥					
≥						;scan the arguments
≠JSR≡≡PC≡≡GETOFS≡≥	056500	004767	775640			JSR PC,GETOFS	;GPHPTR(R2) ← LOC[graph node for offset]
≠TST≡≡R0≡≥	056504	005700				TST R0		;or was there an error?
≠BEQ≡≥	056506	001420				BEQ 1$		;oops.
≤EVSIG≡≥						EVSIG GPHPTR(R2);Signal the event.
≤.ARG≡≥						  .ARG GPHPTR(R2)
≠.LIF≡≥						    .LIF NB GPHPTR(R2)
≠MOV≡≡GPHPTR≡≡R2≡≡SP≡≥	056510	016246	000014			      MOV GPHPTR(R2),-(SP)
≥	056514	104012				104012
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	056516	016200	000010			MOV AGPTR(R2),R0;
≠TSTB≡≡R0≡≥	056522	105710				TSTB (R0)	;At the end?
≠BNE≡≥	056524	001011				BNE 1$		;No.  extra arguments.
≥					
≥						;prepare the answer. Note that TACK and TACKVAL take a string pointer
≥						; in R0 and leave it right afterwords.
≠MOV≡≡ANPTR≡≡R2≡≡R0≡≥	056526	016200	000002			MOV ANPTR(R2),R0	;R0 ← answer pointer
≠MOV≡≡DONEME≡≡R1≡≥	056532	012701	055110			MOV #DONEMES,R1	;
≠JSR≡≡PC≡≡TACK≡≥	056536	004767	777234			JSR PC,TACK	;Tack on "DONE "
≠MOV≡≡R0≡≡ANPTR≡≡R2≡≥	056542	010062	000002			MOV R0,ANPTR(R2);
≠BR≡≥	056546	000402				BR 2$		;Ready to send it back.
≥					
≥						;In this case, cannot make sense of the argument.
≠JMP≡≡DOERR≡≥	056550	000167	775676		1$:	JMP DOERR	;
≥					
≥					2$:	;ANPTR(R2) = end of the message.  ANSBUF(R2) = front of the message
≠JMP≡≡SNDANS≡≥	056554	000167	775752			JMP SNDANS	;Send it winging on its way. Reclaim the answer block.
≥								;Reclaim the PDB.  Dismiss.
≥					
≥					DOWAIT:	;Service routine
≠COMMEN≡≥				COMMENT ⊗ Currently accepted argument string is: (OFFSET n).  The
≥				OFFSET construct will cause that variable in the current interpreter
≥				to be waited.  The answer is of the form "DONE" when the wait is up,
≥				unless something goes wrong, in which case the answer will be "ERROR
≥					(WAIT arg)".  ⊗
≥					
≥						;scan the arguments
≠JSR≡≡PC≡≡GETOFS≡≥	056560	004767	775560			JSR PC,GETOFS	;GPHPTR(R2) ← LOC[graph node for offset]
≠TST≡≡R0≡≥	056564	005700				TST R0		;or was there an error?
≠BEQ≡≥	056566	001420				BEQ 1$		;oops.
≤EVWAIT≡≥						EVWAIT GPHPTR(R2);WAIT the event.
≤.ARG≡≥						  .ARG GPHPTR(R2)
≠.LIF≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 248
	ALAID PAL[HAL,HE]	PAGE 12.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥						    .LIF NB GPHPTR(R2)
≠MOV≡≡GPHPTR≡≡R2≡≡SP≡≥	056570	016246	000014			      MOV GPHPTR(R2),-(SP)
≥	056574	104010				104010
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	056576	016200	000010			MOV AGPTR(R2),R0;
≠TSTB≡≡R0≡≥	056602	105710				TSTB (R0)	;At the end?
≠BNE≡≥	056604	001011				BNE 1$		;No.  extra arguments.
≥					
≥						;prepare the answer. Note that TACK and TACKVAL take a string pointer
≥						; in R0 and leave it right afterwords.
≠MOV≡≡ANPTR≡≡R2≡≡R0≡≥	056606	016200	000002			MOV ANPTR(R2),R0	;R0 ← answer pointer
≠MOV≡≡DONEME≡≡R1≡≥	056612	012701	055110			MOV #DONEMES,R1	;
≠JSR≡≡PC≡≡TACK≡≥	056616	004767	777154			JSR PC,TACK	;Tack on "DONE "
≠MOV≡≡R0≡≡ANPTR≡≡R2≡≥	056622	010062	000002			MOV R0,ANPTR(R2);
≠BR≡≥	056626	000402				BR 2$		;Ready to send it back.
≥					
≥						;In this case, cannot make sense of the argument.
≠JMP≡≡DOERR≡≥	056630	000167	775616		1$:	JMP DOERR	;
≥					
≥					2$:	;ANPTR(R2) = end of the message.  ANSBUF(R2) = front of the message
≠JMP≡≡SNDANS≡≥	056634	000167	775672			JMP SNDANS	;Send it winging on its way. Reclaim the answer block.
≥								;Reclaim the PDB.  Dismiss.
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 249
	ALAID PAL[HAL,HE]	PAGE 13 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  DOSETNAM
≥					
≥					DOSETNAM:	;Service routine
≠COMMEN≡≥				COMMENT ⊗ Currently accepted argument string is: "n".  the
≥				interpreter with that name will be selected, and its ISB placed in
≥				R4.  The answer is of the form "DONE" when the wait is up, unless
≥				something goes wrong, in which case the answer will be "ERROR (SETNAM
≥					arg)".  ⊗
≥					
≥						;scan the arguments
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	056640	016200	000010			MOV AGPTR(R2),R0;
≠JSR≡≡PC≡≡GETOCT≡≥	056644	004767	777042			JSR PC,GETOCT	;R0 ← after the arg, R1 ← octal number seen
≠MOV≡≡R0≡≡AGPTR≡≡R2≡≥	056650	010062	000010			MOV R0,AGPTR(R2);Save arg. ptr
≠MOV≡≡R1≡≡SP≡≥	056654	010146				MOV R1,-(SP)	;Stack interpreter name
≤EVWAIT≡≥						EVWAIT INTEVT	;Enter critical section
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	056656	016746	756426			      MOV INTEVT,-(SP)
≥	056662	104010				104010
≠MOV≡≡ISTBLK≡≡R0≡≥	056664	012700	063222			MOV #ISTBLK,R0	;Find the right interpreter.
≠MOV≡≡R0≡≡R1≡≥	056670	010001			1$:	MOV R0,R1	;
≠MOV≡≡NXTINT≡≡R1≡≡R0≡≥	056672	016100	000002			MOV NXTINT(R1),R0;
≠BEQ≡≥	056676	001424				BEQ 2$		;No such interpreter.
≠CMP≡≡INTNAM≡≡R0≡≡SP≡≥	056700	026016	000026			CMP INTNAM(R0),(SP)	;Have we found ours yet?
≠BNE≡≥	056704	001371				BNE 1$		;No.  Try again.
≤EVSIG≡≥						EVSIG INTEVT	;End of critical section
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	056706	016746	756376			      MOV INTEVT,-(SP)
≥	056712	104012				104012
≠TST≡≡SP≡≥	056714	005726				TST (SP)+	;Get rid of the interpreter name.
≠MOV≡≡R0≡≡CURNAM≡≥	056716	010067	774516			MOV R0,CURNAM	;CURNAM ← ISB of new interpreter
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	056722	016200	000010			MOV AGPTR(R2),R0;
≠TSTB≡≡R0≡≥	056726	105710				TSTB (R0)	;At the end?
≠BNE≡≥	056730	001012				BNE 3$		;No.  extra arguments.
≥					
≥						;prepare the answer. Note that TACK and TACKVAL take a string pointer
≥						; in R0 and leave it right afterwords.
≠MOV≡≡ANPTR≡≡R2≡≡R0≡≥	056732	016200	000002			MOV ANPTR(R2),R0	;R0 ← answer pointer
≠MOV≡≡DONEME≡≡R1≡≥	056736	012701	055110			MOV #DONEMES,R1	;
≠JSR≡≡PC≡≡TACK≡≥	056742	004767	777030			JSR PC,TACK	;Tack on "DONE "
≠BR≡≥	056746	000405				BR 4$		;Ready to send it back.
≥					
≥						;No such interpreter
≤EVSIG≡≥					2$:	EVSIG INTEVT	;End of critical secton
≤.ARG≡≥						  .ARG INTEVT
≠.LIF≡≥						    .LIF NB INTEVT
≠MOV≡≡INTEVT≡≡SP≡≥	056750	016746	756334			      MOV INTEVT,-(SP)
≥	056754	104012				104012
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 250
	ALAID PAL[HAL,HE]	PAGE 13.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					
≥						;In this case, cannot make sense of the argument.
≠JMP≡≡DOERR≡≥	056756	000167	775470		3$:	JMP DOERR	;
≥					
≥					4$:	;ANPTR(R2) = end of the message.  ANSBUF(R2) = front of the message
≠JMP≡≡SNDANS≡≥	056762	000167	775544			JMP SNDANS	;Send it winging on its way. Reclaim the answer block.
≥								;Reclaim the PDB.  Dismiss.
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 251
	ALAID PAL[HAL,HE]	PAGE 14 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  DOSTART, DODDT, DONOTICE
≥					
≥					DOSTART:	;Service routine
≠COMMEN≡≥				COMMENT ⊗ Currently accepted argument string is: (PLACE n), which is
≥				optional.  A new interpreter is started up, either at n or at PCODE,
≥				if the argument is missing.  This new interpreter becomes the
≥				selected interpreter.  The answer is of the form "DONE", unless
≥				something goes wrong, in which case the answer will be "ERROR (START
≥					arg)".  ⊗
≥					
≥						;scan the arguments
≠MOV≡≡AGPTR≡≡R2≡≡R0≡≥	056766	016200	000010			MOV AGPTR(R2),R0;
≠TSTB≡≡R0≡≥	056772	105720				TSTB (R0)+,#'(	;An argument?
≠BEQ≡≥	056774	001413				BEQ 1$
≠JSR≡≡PC≡≡LOOKUP≡≥	056776	004767	776312			JSR PC,LOOKUP	;
≠CMP≡≡R1≡≡PLCCOD≡≥	057002	020127	000005			CMP R1,#PLCCOD	;A place?
≠BNE≡≥	057006	001037				BNE 3$		;No.  Illegal argument
≠JSR≡≡PC≡≡GETOCT≡≥	057010	004767	776676			JSR PC,GETOCT	;R0 ← after the arg, R1 ← number seen.
≠MOV≡≡R0≡≡AGPTR≡≡R2≡≥	057014	010062	000010			MOV R0,AGPTR(R2);Save arg. ptr
≠MOV≡≡R1≡≡R0≡≥	057020	010100				MOV R1,R0	;R0 ← interpreter start address
≠BR≡≥	057022	000402				BR 2$
≠MOV≡≡PCODE≡≡R0≡≥	057024	012700	130000		1$:	MOV #PCODE,R0	;R0 ← interpreter start address
≠CLR≡≡R1≡≥	057030	005001			2$:	CLR R1		;No particular event when he is finished.
≠JSR≡≡PC≡≡SPAWN≡≥	057032	004767	761274			JSR PC,SPAWN	;R0 ← PDB[new interpreter process].
≠MOV≡≡PDBR4≡≡R0≡≡CURNAM≡≥	057036	016067	000036	774374		MOV PDBR4(R0),CURNAM	;Set current interpreter to this one.
≤SCHEDU≡≥						SCHEDU R0,#INTERP,#1,#2;Cause the new process to be started, suspended
≤.ARG≡≥						  .ARG #2
≠.LIF≡≥						    .LIF NB #2
≠MOV≡≡SP≡≥	057044	012746	000002			      MOV #2,-(SP)
≤.ARG≡≥						  .ARG #1
≠.LIF≡≥						    .LIF NB #1
≠MOV≡≡SP≡≥	057050	012746	000001			      MOV #1,-(SP)
≤.ARG≡≥						  .ARG #INTERP
≠.LIF≡≥						    .LIF NB #INTERP
≠MOV≡≡INTERP≡≡SP≡≥	057054	012746	036016			      MOV #INTERP,-(SP)
≤.ARG≡≥						  .ARG R0
≠.LIF≡≥						    .LIF NB R0
≠MOV≡≡R0≡≡SP≡≥	057060	010046				      MOV R0,-(SP)
≥	057062	104016				104016
≥					
≥						;prepare the answer. Note that TACK and TACKVAL take a string pointer
≥						; in R0 and leave it right afterwords.
≠MOV≡≡ANPTR≡≡R2≡≡R0≡≥	057064	016200	000002			MOV ANPTR(R2),R0	;R0 ← answer pointer
≠MOV≡≡DONEME≡≡R1≡≥	057070	012701	055110			MOV #DONEMES,R1	;
≠JSR≡≡PC≡≡TACK≡≥	057074	004767	776676			JSR PC,TACK	;Tack on "DONE "
≠MOV≡≡R0≡≡ANPTR≡≡R2≡≥	057100	010062	000002			MOV R0,ANPTR(R2);
≠BR≡≥	057104	000402				BR 4$		;Ready to send it back.
≥					
≥						;In this case, cannot make sense of the argument.
≠JMP≡≡DOERR≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 252
	ALAID PAL[HAL,HE]	PAGE 14.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	057106	000167	775340		3$:	JMP DOERR
≥					
≥					4$:	;ANPTR(R2) = end of the message.  ANSBUF(R2) = front of the message
≠JMP≡≡SNDANS≡≥	057112	000167	775414			JMP SNDANS	;Send it winging on its way. Reclaim the answer block.
≥								;Reclaim the PDB.  Dismiss.
≥					
≥					DODDT:	;Service routine
≠COMMEN≡≥				COMMENT ⊗ Jump to DDT, so that ↑P will proceed. The answer is of the
≥				form "DONE", unless something goes wrong, in which case the answer
≥					will be "ERROR (DDT arg)".  ⊗
≥					
≤HALERR≡≥						HALERR DODDTMES	;Here we go to DDT.
≠MOV≡≡DODDTM≡≡SP≡≥	057116	012746	057234			MOV #DODDTMES,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	057122	004777	734664			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≥					
≥						;test stuff.  Current test:  Try the turn-around question YOUTHERE
≥						;at the ten.
≠MOV≡≡R3≡≡SP≡≥	057126	010346				MOV R3,-(SP)	;Save R3
≠JSR≡≡PC≡≡MAKREQ≡≥	057130	004767	775510			JSR PC,MAKREQ	;R3 ← request block.
≠MOV≡≡REQPTR≡≡R3≡≡R0≡≥	057134	016300	000002			MOV REQPTR(R3),R0	;R0 ← REQPTR
≠MOV≡≡YTHMES≡≡R1≡≥	057140	012701	055125			MOV #YTHMES,R1	;Tack on "YOUTHERE"
≠JSR≡≡PC≡≡TACK≡≥	057144	004767	776626			JSR PC,TACK	;
≠MOV≡≡R0≡≡REQPTR≡≡R3≡≥	057150	010063	000002			MOV R0,REQPTR(R3)
≠JSR≡≡PC≡≡SNDREQ≡≥	057154	004767	775532			JSR PC,SNDREQ	;Send the request on its way, and eventually come back
≥								;with response in the REQRES(R3)
≠MOV≡≡REQRES≡≡R3≡≡R0≡≥	057160	016300	000004			MOV REQRES(R3),R0	;
≠ADD≡≡MESBEG≡≡R0≡≥	057164	062700	000006			ADD #MESBEG,R0	;Print out the response
≠JSR≡≡PC≡≡TYPSTR≡≥	057170	004767	734704			JSR PC,TYPSTR	;
≠MOV≡≡REQRES≡≡R3≡≡R0≡≥	057174	016300	000004			MOV REQRES(R3),R0	;Reclaim the response buffer
≠JSR≡≡PC≡≡RLFREE≡≥	057200	004767	751404			JSR PC,RLFREE	;
≠MOV≡≡R3≡≡R0≡≥	057204	010300				MOV R3,R0	;Reclaim request block
≠JSR≡≡PC≡≡RLFREE≡≥	057206	004767	751376			JSR PC,RLFREE	;
≠MOV≡≡SP≡≡R3≡≥	057212	012603				MOV (SP)+,R3	;Restore R3
≥					
≥						;prepare the answer. Note that TACK and TACKVAL take a string pointer
≥						; in R0 and leave it right afterwords.
≠MOV≡≡ANPTR≡≡R2≡≡R0≡≥	057214	016200	000002			MOV ANPTR(R2),R0	;R0 ← answer pointer
≠MOV≡≡DONEME≡≡R1≡≥	057220	012701	055110			MOV #DONEMES,R1	;
≠JSR≡≡PC≡≡TACK≡≥	057224	004767	776546			JSR PC,TACK	;Tack on "DONE "
≥					
≥						;ANPTR(R2) = end of the message.  ANSBUF(R2) = front of the message
≠JMP≡≡SNDANS≡≥	057230	000167	775276			JMP SNDANS	;Send it winging on its way. Reclaim the answer block.
≥								;Reclaim the PDB.  Dismiss.
≥					
≤ASCIE≡≥					DODDTMES:  ASCIE </SWITCHING TO DDT/>
≠.ASCIZ≡≥	057234	   123		
≥	057235	   127		
≥	057236	   111		
≥	057237	   124		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 253
	ALAID PAL[HAL,HE]	PAGE 14.2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	057240	   103		
≥	057241	   110		
≥	057242	   111		
≥	057243	   116		
≥	057244	   107		
≥	057245	   040		
≥	057246	   124		
≥	057247	   117		
≥	057250	   040		
≥	057251	   104		
≥	057252	   104		
≥	057253	   124		
≥	057254	   000		
≥					       .ASCIZ /SWITCHING TO DDT/
≠.EVEN≡≥		057256			       .EVEN
≥					
≥					DONOTICE:	;Service routine
≠COMMEN≡≥				COMMENT ⊗ The assumption is that someone has moved the arm.  Call
≥				MOVED to invalidate all devices and cause good values to be
≥				generated.  Return a response of the form "DONE", unless something
≥				goes wrong, in which case the answer will be "ERROR (NOTICE)", which
≥					really ought not to happen.  ⊗
≥					
≠JSR≡≡PC≡≡NOTICE≡≥	057256	004767	766256			JSR PC,NOTICE	;Do the updating.
≥						;prepare the answer. Note that TACK and TACKVAL take a string pointer
≥						; in R0 and leave it right afterwords.
≠MOV≡≡ANPTR≡≡R2≡≡R0≡≥	057262	016200	000002			MOV ANPTR(R2),R0;R0 ← answer pointer
≠MOV≡≡DONEME≡≡R1≡≥	057266	012701	055110			MOV #DONEMES,R1	;
≠JSR≡≡PC≡≡TACK≡≥	057272	004767	776500			JSR PC,TACK	;Tack on "DONE "
≥					
≥						;ANPTR(R2) = end of the message.  ANSBUF(R2) = front of the message
≠JMP≡≡SNDANS≡≥	057276	000167	775230			JMP SNDANS	;Send it winging on its way. Reclaim the answer block.
≥								;Reclaim the PDB.  Dismiss.
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 254
	ALAID PAL[HAL,HE]	PAGE 15 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  Driver for test of communications, ALINIT
≥					
≠.IFNZ≡≡DEBUG≡≥		000000			.IFNZ DEBUG
≥					
≥						PUTLOC JOBDAT, MAINBL
≥						PUTLOC JOBSA, START
≥					MAINBL:	PDBLK 400,S	;Makes a process descriptor for main process
≥					START:	JSR PC,IOINIT	;
≥						JSR PC,FRINIT	;
≥						CLR NOTB10	;
≥						CLR NOTB11	;
≥						MOV #376,167036	;MAPUI
≥						MOV #576,167026	;MAPUD
≥						EVMAK		;Create and signal once the AL interlock event.
≥						MOV (SP),ALDEVT	;
≥						EVSIG		;
≥						CLR WAITQ+QNEXT	;
≥						JMP SERVER	;No, he'll never return
≥					
≥					
≥					GETARG:	MOV R0,FAKE	;
≥						MOV #FAKE1,R0	;
≥						RTS PC
≥					
≥					FAKE:	.BLKW 2	;Long enough for floating
≥					FAKE1:	FAKE
≥					
≥					ROUTINE GETVAL,<GTV.ARG>
≥						MOV GTV.ARG(RF),R0
≥						RTS RF
≥					
≥					ROUTINE CHANGE,<CHG.ND,CHG.VN>
≥						RTS RF
≥					
≥					GETSCA:	MOV #FAKE,R0	;
≥						MOV R0,-(R3)	;
≥						RTS PC		;
≥					
≥					GETTRN:	MOV #60,R0	;
≥						JSR PC,GTFREE	;
≥						MOV R0,-(R3)	;
≥					
≥					TACKVAL:
≥					COMMENT ⊗ R1 = LOC[value], R0 ← where to put it ⊗
≥						MOV #FAKEMES,R1	;
≥						JMP TACK	;
≥					FAKEMES:ASCIE </999.999/>
≥					
≥					.ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 255
	ALAID PAL[HAL,HE]	PAGE 15.1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					
≤PDBLK≡≥					ALPDB:	PDBLK 210,S	;Makes a process descriptor for server
≠.IF≡≥						.IF NB S
≠.IF≡≥						  .IF IDN <S>,<D>
≥						    .W.==UFPUSE+UDPUSE
≥						    .L.==66
≥						  .IFF
≡UFPUSE≡≡.W.≠≥		100000				    .W.==UFPUSE
≡.L.≠≥		000036				    .L.==36
≥						  .ENDC
≥						.IFF
≥						  .W.==0
≥						  .L.==0
≥						.ENDC
≠.WORD≡≡.W.≡≥	057302	100000				.WORD .W.
≠.WORD≡≡UFEC≡≡UST0≡≡.L.≡≥	057304	000520				.WORD <UFEC-UST0>+.L.+<2*210>
≠.BLKB≡≡UIMAP≡≡USKMIN≡≥		057324				.BLKB UIMAP-USKMIN
≠.WORD≡≥	057324	000376				.WORD 376
≠.WORD≡≥	057326	000376				.WORD 376
≠.BLKB≡≡UFEC≡≡PDBR0≡≥		057344				.BLKB UFEC-PDBR0
≠.BLKB≡≡.L.≡≥		060022				.BLKB 2*210+.L.
≥					
≥					ALINIT:
≠COMMEN≡≥					COMMENT ⊗ Start up one copy of the server as a separate job. ⊗
≤EVMAK≡≥						EVMAK		;Create and signal once the AL interlock event.
≥	060022	104004				104004
≠MOV≡≡SP≡≡ALDEVT≡≥	060024	011667	773412			MOV (SP),ALDEVT	;
≤EVSIG≡≥						EVSIG		;
≤.ARG≡≥						  .ARG 
≠.LIF≡≥						    .LIF NB 
≥						      MOV ,-(SP)
≥	060030	104012				104012
≠CLR≡≡WAITQ≡≡QNEXT≡≥	060032	005067	773406			CLR WAITQ+QNEXT	;
≠MOV≡≡R0≡≥	060036	012700	000020			MOV #20,R0	;R3 stack space
≠JSR≡≡PC≡≡GTFREE≡≥	060042	004767	750200			JSR PC,GTFREE	;
≠ADD≡≡R0≡≥	060046	062700	000020			ADD #20,R0	;to end of space
≠MOV≡≡R0≡≡SP≡≥	060052	010046				MOV R0,-(SP)	;Save stack space
≠MOV≡≡R0≡≥	060054	012700	000210			MOV #210,R0	;Room for process descriptor
≠JSR≡≡PC≡≡GTFREE≡≥	060060	004767	750162			JSR PC,GTFREE	;R0 ← LOC[new process descriptor]
≠MOV≡≡UFPUSE≡≡UGRSAV≡≡PDBSTA≡≡R0≡≥	060064	012760	104000	000000		MOV #UFPUSE+UGRSAV,PDBSTA(R0);Use floating point, use saved registers.
≠MOV≡≡UPDLEN≡≡R0≡≥	060072	012760	000420	000002		MOV #420,UPDLEN(R0)	;Length of PDB
≠MOV≡≡R0≡≡R1≡≥	060100	010001				MOV R0,R1	;
≠ADD≡≡R1≡≥	060102	062701	000420			ADD #420,R1	;
≠MOV≡≡R1≡≡PDBSP≡≡R0≡≥	060106	010160	000014			MOV R1,PDBSP(R0)	;Store away the new stack pointer (reg 6)
≠MOV≡≡SERVER≡≡PDBPC≡≡R0≡≥	060112	012760	053610	000016		MOV #SERVER,PDBPC(R0);Store away the new PC
≠MOV≡≡SP≡≡PDBR3≡≡R0≡≥	060120	012660	000034			MOV (SP)+,PDBR3(R0)	;Store away the R3 stack pointer.
≠MOV≡≡ISTBLK≡≡R1≡≥	060124	012701	063222			MOV #ISTBLK,R1	;
≠MOV≡≡UIMAP≡≡R0≡≥	060130	012760	000376	000022		MOV #376,UIMAP(R0)	;Map instruction space
≠MOV≡≡UDMAP≡≡R0≡≥	060136	012760	000576	000024	        MOV #576,UDMAP(R0)  ;Sets data space to map 1, which puts phys 160000
≠ADD≡≡PDBSTA≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 256
	ALAID PAL[HAL,HE]	PAGE 15.2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥	060144	062700	000000			ADD #PDBSTA,R0	;Move R0 to the middle of the process descriptor
≤SCHEDU≡≥						SCHEDU R0,#SERVER,#2,#2;Cause the new process to be started, suspended
≤.ARG≡≥						  .ARG #2
≠.LIF≡≥						    .LIF NB #2
≠MOV≡≡SP≡≥	060150	012746	000002			      MOV #2,-(SP)
≤.ARG≡≥						  .ARG #2
≠.LIF≡≥						    .LIF NB #2
≠MOV≡≡SP≡≥	060154	012746	000002			      MOV #2,-(SP)
≤.ARG≡≥						  .ARG #SERVER
≠.LIF≡≥						    .LIF NB #SERVER
≠MOV≡≡SERVER≡≡SP≡≥	060160	012746	053610			      MOV #SERVER,-(SP)
≤.ARG≡≥						  .ARG R0
≠.LIF≡≥						    .LIF NB R0
≠MOV≡≡R0≡≡SP≡≥	060164	010046				      MOV R0,-(SP)
≥	060166	104016				104016
≠RTS≡≡PC≡≥	060170	000207				RTS PC
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 257
	ALAID PAL[HAL,HE]	PAGE 16 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  BUGS
≠COMMEN≡≥				COMMENT ⊗
≥				DOSTART calls SPAWN, which expects R4 to point to a valid ISB.  This
≥				is not always possible, so either SPAWN should be changed, or, more
≥				likely, a special version of SPAWN should be used that sets up an ISB
≥				from scratch, much as is done in HAL(3P).
≥					⊗
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 258
	HAL PAL[HAL,HE]	PAGE 2.6 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					.ENDC
≥					
≠.IFNZ≡≡GRAPHS≡≥		000001			.IFNZ GRAPHS		;Graph structure
≠.INSRT≡≥					    .INSRT GRAPHS.PAL[HAL,HE]
≠COMMEN≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 259
	GRAPHS PAL[HAL,HE]	PAGE 1 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥				COMMENT ⊗   VALID 00013 PAGES
≥				C REC  PAGE   DESCRIPTION
≥				C00001 00001
≥				C00002 00002	  Data structures, GSINIT
≥				C00006 00003	  UNLINK, NEWCEL
≥				C00009 00004	  NXTTIM
≥				C00010 00005	  INVLDT, INVLR0
≥				C00012 00006	  CHANGE, CHNGER
≥				C00018 00007	  ADDCHG
≥				C00020 00008	  GETVAL, GETVR0
≥				C00022 00009	  EVALND, EVLEXP
≥				C00030 00010	  MAKEXP, ADDCLC, REMCLC, DELEXP
≥				C00038 00011	  MAKEVN, DELVN
≥				C00045 00012	  MGNDS  marking method for gnodes
≥				C00059 00013	  Known Bugs
≥				C00062 ENDMK
≥					C⊗;
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 260
	GRAPHS PAL[HAL,HE]	PAGE 2 	FLOATING POINT TO/FROM STRING CONVERSION ROUTINES

≥					;  Data structures, GSINIT
≥					
≠.SBTTL≡≥					.SBTTL Graph routines.
≥					;Graph structure definitions
≥					;RHT 9/74  RF 6/75, 10/75
≥					
≠COMMEN≡≥				COMMENT ⊗  
≥				This is the runtime's prime evil,
≥				The murderous graph nodes and interlocks.
≥					⊗
≥					
≥					;GRAPH NODES		;Common fields for Variables and Expressions
≡II≠≥		000000				II==0
≤XX≡≥						XX  GNMODE	;Mode bits.  1:variable. 2:expression
≠.IFDF≡≡GNMODE≡≥						   .IFDF GNMODE
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using GNMODE in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡GNMODE≠≥		000000				    GNMODE == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX  NXTGN	;Links all graph nodes.  Points to next one.
≠.IFDF≡≡NXTGN≡≥						   .IFDF NXTGN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NXTGN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NXTGN≠≥		000002				    NXTGN == II
≡II≡≡II≠≥		000004				    II == II+2
≤XX≡≥						XX  PRVGN	;Previous link in that chain
≠.IFDF≡≡PRVGN≡≥						   .IFDF PRVGN
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using PRVGN in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡PRVGN≠≥		000004				    PRVGN == II
≡II≡≡II≠≥		000006				    II == II+2
≤XX≡≥						XX  INVMRK	;0 => valid, other => invalid
≠.IFDF≡≡INVMRK≡≥						   .IFDF INVMRK
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using INVMRK in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡INVMRK≠≥		000006				    INVMRK == II
≡II≡≡II≠≥		000010				    II == II+2
≤XX≡≥						XX  GNVAL	;points at the value cell
≠.IFDF≡≡GNVAL≡≥						   .IFDF GNVAL
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using GNVAL in two ways!!!
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 261
	GRAPHS PAL[HAL,HE]	PAGE 2.1 	Graph routines.

≥						       .ENDC
≥						   .ENDC
≡II≡≡GNVAL≠≥		000010				    GNVAL == II
≡II≡≡II≠≥		000012				    II == II+2
≤XX≡≥						XX  GNDEPS	;list of dependents (variables or expressions)
≠.IFDF≡≡GNDEPS≡≥						   .IFDF GNDEPS
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using GNDEPS in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡GNDEPS≠≥		000012				    GNDEPS == II
≡II≡≡II≠≥		000014				    II == II+2
≡II≡≡GNEND≠≥		000014				GNEND==II	;marks the end of the common region
≥					
≥					;VARIABLE NODES		;Explicitly released, formed from large block store.
≡GNEND≡≡II≠≥		000014				II==GNEND
≤XX≡≥						XX  VALIDF	;a count which is incremented at every reevaluation
≠.IFDF≡≡VALIDF≡≥						   .IFDF VALIDF
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using VALIDF in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡VALIDF≠≥		000014				    VALIDF == II
≡II≡≡II≠≥		000016				    II == II+2
≤XX≡≥						XX  VNCLCS	;list of expression nodes used as calculators
≠.IFDF≡≡VNCLCS≡≥						   .IFDF VNCLCS
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using VNCLCS in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡VNCLCS≠≥		000016				    VNCLCS == II
≡II≡≡II≠≥		000020				    II == II+2
≤XX≡≥						XX  VNCHGS	;list of change cells. (see format below)
≠.IFDF≡≡VNCHGS≡≥						   .IFDF VNCHGS
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using VNCHGS in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡VNCHGS≠≥		000020				    VNCHGS == II
≡II≡≡II≠≥		000022				    II == II+2
≡II≡≡VNDSIZ≠≥		000011				VNDSIZ == II/2	;Length of variable node (in words)
≥					
≥					;EXPRESSION NODES	;Explicitly released, formed from large block store.
≡GNEND≡≡II≠≥		000014				II==GNEND
≤XX≡≥						XX  ENISB	;the ISB for this expression
≠.IFDF≡≡ENISB≡≥						   .IFDF ENISB
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using ENISB in two ways!!!
≥						       .ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 262
	GRAPHS PAL[HAL,HE]	PAGE 2.2 	Graph routines.

≥						   .ENDC
≡II≡≡ENISB≠≥		000014				    ENISB == II
≡II≡≡II≠≥		000016				    II == II+2
≤XX≡≥						XX  ENIPC	;the IPC for this expression
≠.IFDF≡≡ENIPC≡≥						   .IFDF ENIPC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using ENIPC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡ENIPC≠≥		000016				    ENIPC == II
≡II≡≡II≠≥		000020				    II == II+2
≤XX≡≥						XX  ENNEED	;list of needed nodes (cell-linked)
≠.IFDF≡≡ENNEED≡≥						   .IFDF ENNEED
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using ENNEED in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡ENNEED≠≥		000020				    ENNEED == II
≡II≡≡II≠≥		000022				    II == II+2
≡II≡≡ENDSIZ≠≥		000011				ENDSIZ == II/2	;Length of expression node (in words)
≥					
≥					;CELL LINKS
≡II≠≥		000000				II==0
≤XX≡≥						XX  CAR	
≠.IFDF≡≡CAR≡≥						   .IFDF CAR	
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using CAR	 in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡CAR≠≥		000000				    CAR	 == II
≡II≡≡II≠≥		000002				    II == II+2
≤XX≡≥						XX  CDR	
≠.IFDF≡≡CDR≡≥						   .IFDF CDR	
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using CDR	 in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡CDR≠≥		000002				    CDR	 == II
≡II≡≡II≠≥		000004				    II == II+2
≥					
≥					;CHANGER CELL		;Explicitly released, formed from large block store.
≡II≠≥		000000				II==0
≤XX≡≥						XX  NXTCHG	;next changer cell in chain
≠.IFDF≡≡NXTCHG≡≥						   .IFDF NXTCHG
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using NXTCHG in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡NXTCHG≠≥		000000				    NXTCHG == II
≡II≡≡II≠	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 263
	GRAPHS PAL[HAL,HE]	PAGE 2.3 	Graph routines.

≥		000002				    II == II+2
≤XX≡≥						XX  CHGISB	;Points to interpreter status block to resolve addressing
≠.IFDF≡≡CHGISB≡≥						   .IFDF CHGISB
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using CHGISB in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡CHGISB≠≥		000002				    CHGISB == II
≡II≡≡II≠≥		000004				    II == II+2
≤XX≡≥						XX  CHGIPC	;the interpeter PC where the calculation starts
≠.IFDF≡≡CHGIPC≡≥						   .IFDF CHGIPC
≠.IF1≡≥						       .IF1
≥						       .ERROR You are using CHGIPC in two ways!!!
≥						       .ENDC
≥						   .ENDC
≡II≡≡CHGIPC≠≥		000004				    CHGIPC == II
≡II≡≡II≠≥		000006				    II == II+2
≡II≡≡CHGCSZ≠≥		000003				CHGCSZ == II/2	;Size of changer cell, in words
≥					
≠.BLKW≡≥		060174			GNODES:  .BLKW 1	;head of chain of graph nodes.
≥	060174	000000			TIME:	0		;used during evaluation of nodes
≥	060176	000000			VALIDNO:0		;used for validity field of nodes
≠.BLKW≡≥		060202			GNEVT:	.BLKW 1		;event for interlocking graph references
≥					
≥					GSINIT:
≥					;Initialize the graph structure to a null situation;
≤EVMAK≡≥						EVMAK	;Make a new interlock event.
≥	060202	104004				104004
≠MOV≡≡SP≡≡GNEVT≡≥	060204	011667	777770			MOV (SP),GNEVT;
≤EVSIG≡≥						EVSIG 	;Give it one signal.
≤.ARG≡≥						  .ARG 
≠.LIF≡≥						    .LIF NB 
≥						      MOV ,-(SP)
≥	060210	104012				104012
≠CLR≡≡GNODES≡≥	060212	005067	777754			CLR GNODES;
≠CLR≡≡TIME≡≥	060216	005067	777752			CLR TIME;
≠CLR≡≡VALIDN≡≥	060222	005067	777750			CLR VALIDNO;
≠RTS≡≡PC≡≥	060226	000207				RTS PC	;Done
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 264
	GRAPHS PAL[HAL,HE]	PAGE 3 	Graph routines.

≥					;  UNLINK, NEWCEL
≥					
≥					UNLINK:
≠COMMEN≡≥				COMMENT ⊗ A list is in R0, and an entity in R1.  All occurrences of
≥				that entity, if any, are removed from the list.  The orphaned cells
≥				are left for the garbage collector.  A pointer to the list is
≥					returned in R0 (it has changed if the first element was deleted).  ⊗
≠MOV≡≡R2≡≡SP≡≥	060230	010246				MOV R2,-(SP)		;Save R2
≠MOV≡≡R3≡≡SP≡≥	060232	010346				MOV R3,-(SP)		;Save R3
≠MOV≡≡R0≡≡R2≡≥	060234	010002				MOV R0,R2		;R2 ← forward pointer
≠BEQ≡≥	060236	001420				BEQ 3$			;If no list, then done
≠MOV≡≡R1≡≡SP≡≥	060240	010146				MOV R1,-(SP)		;Save R1
≠JSR≡≡PC≡≡NEWCEL≡≥	060242	004767	000050			JSR PC,NEWCEL		;R0 ← dummy header  NOTE: don't end critical
≥									;section til return from UNLINK
≠MOV≡≡SP≡≡R1≡≥	060246	012601				MOV (SP)+,R1		;Restore R1
≠MOV≡≡R2≡≡CDR≡≡R0≡≥	060250	010260	000002			MOV R2,CDR(R0)		;Set up dummy header
≠MOV≡≡R0≡≡R3≡≥	060254	010003				MOV R0,R3		;R3 ← backward pointer
≠CMP≡≡CAR≡≡R2≡≡R1≡≥	060256	026201	000000		1$:	CMP CAR(R2),R1		;Match?
≠BEQ≡≥	060262	001411				BEQ 4$			;Yes
≠MOV≡≡R2≡≡R3≡≥	060264	010203				MOV R2,R3		;
≠MOV≡≡CDR≡≡R2≡≡R2≡≥	060266	016202	000002		2$:	MOV CDR(R2),R2		;Move along
≠BNE≡≥	060272	001371				BNE 1$			;If any more
≠MOV≡≡CDR≡≡R0≡≡R0≡≥	060274	016000	000002			MOV CDR(R0),R0		;Go past dummy
≠MOV≡≡SP≡≡R3≡≥	060300	012603			3$:	MOV (SP)+,R3		;Restore R3
≠MOV≡≡SP≡≡R2≡≥	060302	012602				MOV (SP)+,R2		;Restore R2
≠RTS≡≡PC≡≥	060304	000207				RTS PC			;Return
≠MOV≡≡CDR≡≡R2≡≡CDR≡≡R3≡≥	060306	016263	000002	000002	4$:	MOV CDR(R2),CDR(R3)	;Link past the orphan
≠BR≡≥	060314	000764				BR  2$			;Continue
≥					
≥					NEWCEL:
≠COMMEN≡≥				COMMENT ⊗ Returns in R0 a pointer at a cell.  Taken from cell space
≥				unless there is none.  Uses direct jumps, lets the subsidiary do the
≥					return. ⊗
≠.IFNZ≡≡SMALLB≡≥		000001			    .IFNZ SMALLB
≠MOV≡≡CELSPC≡≡R0≡≥	060316	012700	035016			MOV #CELSPC,R0	;
≠JMP≡≡GETSBK≡≥	060322	000167	753130			JMP GETSBK	;Allocate from small blocks
≥					    .IFF
≥						MOV #2,R0	;Number of words needed
≥						JMP GTFREE	;R0 ← LOC[new block]
≥					    .ENDC
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 265
	GRAPHS PAL[HAL,HE]	PAGE 4 	Graph routines.

≥					;  NXTTIM
≥					
≠COMMEN≡≥				COMMENT ⊗
≥					JSR	PC,NXTTIM
≥				 	
≥				Returns TIME←TIME+1 in R0.  If TIME goes negative then set all
≥					positive mark cells to negative, then set time to 1. ⊗
≥					
≥					
≠INC≡≡TIME≡≥	060326	005267	777642		NXTTIM:	INC	TIME		;TIME←TIME+1
≠MOV≡≡TIME≡≡R0≡≥	060332	016700	777636			MOV	TIME,R0
≠BGT≡≥	060336	003016				BGT	4$		;OK?
≠MOV≡≡GNODES≡≡R0≡≥	060340	016700	777626			MOV	GNODES,R0	;
≠BEQ≡≥	060344	001410				BEQ	3$		;DID WE HAVE ANY??
≠TST≡≡INVMRK≡≡R0≡≥	060346	005760	000006		1$:	TST	INVMRK(R0)	;YES
≠BLE≡≥	060352	003402				BLE	2$		;WAS INVMRK POSITIVE
≠NEG≡≡INVMRK≡≡R0≡≥	060354	005460	000006			NEG	INVMRK(R0)	;YES, NEGATE IT
≠MOV≡≡NXTGN≡≡R0≡≡R0≡≥	060360	016000	000002		2$:	MOV	NXTGN(R0),R0	;GO ON TO NEXT
≠BNE≡≥	060364	001370				BNE	1$		;IF ANY
≠INC≡≡R0≡≥	060366	005200			3$:	INC	R0		;R0←0+1
≠MOV≡≡R0≡≡TIME≡≥	060370	010067	777600			MOV	R0,TIME		;TIME IS 1 AGAIN
≠RTS≡≡PC≡≥	060374	000207			4$:	RTS	PC
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 266
	GRAPHS PAL[HAL,HE]	PAGE 5 	Graph routines.

≥					;  INVLDT, INVLR0
≥					
≥					INVLDT:	
≠COMMEN≡≥				COMMENT ⊗ Called only from the outside world.  R0 is the node to
≥				invalidate, along with all dependents.  We must invalidate dependents
≥				even if the given node is already invalid, unless we have just now
≥					invalidated it, which would imply that we are in a cycle.  ⊗
≤EVWAIT≡≥						EVWAIT	GNEVT		;We change TIME, so must lock this
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	060376	016746	777576			      MOV GNEVT,-(SP)
≥	060402	104010				104010
≠MOV≡≡R0≡≡R1≡≥	060404	010001				MOV	R0,R1
≠JSR≡≡PC≡≡NXTTIM≡≥	060406	004767	777714			JSR	PC,NXTTIM
≠MOV≡≡R1≡≡R0≡≥	060412	010100				MOV	R1,R0
≠JSR≡≡PC≡≡INVLR0≡≥	060414	004767	000010			JSR	PC,INVLR0
≤EVSIG≡≥						EVSIG	GNEVT		;End of critical section
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	060420	016746	777554			      MOV GNEVT,-(SP)
≥	060424	104012				104012
≠RTS≡≡PC≡≥	060426	000207				RTS	PC
≥					
≠CMP≡≡INVMRK≡≡R0≡≡TIME≡≥	060430	026067	000006	777536	INVLR0:	CMP	INVMRK(R0),TIME	;Are we in a cycle?
≠BEQ≡≥	060436	001417				BEQ	4$		;Yes.  Return.
≠MOV≡≡TIME≡≡INVMRK≡≡R0≡≥	060440	016760	777530	000006	1$:	MOV	TIME,INVMRK(R0)	;No.  Invalidate this node.
≠MOV≡≡R2≡≡SP≡≥	060446	010246				MOV	R2,-(SP)	;Save R2 for recursive call
≠MOV≡≡GNDEPS≡≡R0≡≡R2≡≥	060450	016002	000012			MOV	GNDEPS(R0),R2	;R2 ← list of dependents
≠BEQ≡≥	060454	001407				BEQ	3$		;If any 
≠MOV≡≡CAR≡≡R2≡≡R0≡≥	060456	016200	000000		2$:	MOV	CAR(R2),R0	;R0 ← next dependent
≠JSR≡≡PC≡≡INVLR0≡≥	060462	004767	777742			JSR	PC,INVLR0	;Go Invalidate it.
≠MOV≡≡CDR≡≡R2≡≡R2≡≥	060466	016202	000002			MOV	CDR(R2),R2	;Repeat for the rest
≠BNE≡≥	060472	001371				BNE	2$		;If any
≠MOV≡≡SP≡≡R2≡≥	060474	012602			3$:	MOV	(SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	060476	000207			4$:	RTS	PC
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 267
	GRAPHS PAL[HAL,HE]	PAGE 6 	Graph routines.

≥					;  CHANGE, CHNGER
≥					
≠COMMEN≡≥				COMMENT ⊗ Called by the outside world to put a new value, CHG.VNEW,
≥					in the variable node CHG.ND.  Returns with CHG.ND in R0. ⊗
≥					
≤ROUTIN≡≥					ROUTINE CHANGE,<CHG.ND,CHG.VNEW>
≠.IFNB≡≥					           .IFNB CHG.ND,CHG.VNEW
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<CHG.ND,CHG.VNEW>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000004			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<CHG.ND,CHG.VNEW>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡CHG.ND≡≥					                  .IFDF CHG.ND
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for CHG.ND
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡CHG.ND≠≥		000004			                   CHG.ND == NNNN
≡NNNN≡≡NNNN≠≥		000002			                   NNNN == NNNN-2
≠.IFDF≡≡CHG.VN≡≥					                  .IFDF CHG.VNEW
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for CHG.VNEW
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡CHG.VN≠≥		000002			                   CHG.VNEW == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					CHANGE:
≠MOV≡≡R2≡≡SP≡≥	060500	010246				MOV	R2,-(SP)	;Save R2
≠MOV≡≡R3≡≡SP≡≥	060502	010346				MOV	R3,-(SP)	;Save R3
≠MOV≡≡CHG.ND≡≡RF≡≡R1≡≥	060504	016501	000004			MOV	CHG.ND(RF),R1	;R1 ← the target node.
≤EVWAIT≡≥						EVWAIT	GNEVT		;Wait until OK to enter critical code.
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	060510	016746	777464			      MOV GNEVT,-(SP)
≥	060514	104010				104010
≠JSR≡≡PC≡≡NXTTIM≡≥	060516	004767	777604			JSR	PC,NXTTIM	;
≠MOV≡≡R1≡≡R0≡≥	060522	010100				MOV	R1,R0		;
≠JSR≡≡PC≡≡INVLR0≡≥	060524	004767	777700			JSR	PC,INVLR0	;invalidate it for the nonce
≠MOV≡≡CHG.ND≡≡RF≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 268
	GRAPHS PAL[HAL,HE]	PAGE 6.1 	Graph routines.

≥	060530	016500	000004			MOV	CHG.ND(RF),R0	;R0 ← the target node
≠MOV≡≡GNVAL≡≡R0≡≡R2≡≥	060534	016002	000010			MOV	GNVAL(R0),R2	;R2 ← old value
≠MOV≡≡CHG.VN≡≡RF≡≡GNVAL≡≡R0≡≥	060540	016560	000002	000010		MOV	CHG.VNEW(RF),GNVAL(R0) ;stow the new value
≠MOV≡≡VNCHGS≡≡R0≡≡R3≡≥	060546	016003	000020			MOV	VNCHGS(R0),R3	;R3 ← list of changers
≠BEQ≡≥	060552	001413				BEQ	2$		;if any
≤EVSIG≡≥						EVSIG	GNEVT		;Leave the overall graph node critical region.
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	060554	016746	777420			      MOV GNEVT,-(SP)
≥	060560	104012				104012
≠JSR≡≡PC≡≡CHNGER≡≥	060562	004767	000052		1$:	JSR	PC,CHNGER	;Call the next change routine
≠MOV≡≡NXTCHG≡≡R3≡≡R3≡≥	060566	016303	000000			MOV	NXTCHG(R3),R3	;R3 ← next changer
≠BNE≡≥	060572	001373				BNE	1$
≤EVWAIT≡≥						EVWAIT	GNEVT		;Enter critical section again.
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	060574	016746	777400			      MOV GNEVT,-(SP)
≥	060600	104010				104010
≠MOV≡≡CHG.ND≡≡RF≡≡R0≡≥	060602	016500	000004		2$:	MOV	CHG.ND(RF),R0	;R0 ← the target node
≠CLR≡≡INVMRK≡≡R0≡≥	060606	005060	000006			CLR	INVMRK(R0)	;Revalidate it
≠INC≡≡VALIDN≡≥	060612	005267	777360			INC	VALIDNO		;A new validity number
≠MOV≡≡VALIDN≡≡VALIDF≡≡R0≡≥	060616	016760	777354	000014		MOV	VALIDNO,VALIDF(R0)	;which is put in the validf
≤EVSIG≡≥						EVSIG	GNEVT		;Ok for others to enter critical code now.
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	060624	016746	777350			      MOV GNEVT,-(SP)
≥	060630	104012				104012
≠MOV≡≡SP≡≡R3≡≥	060632	012603				MOV	(SP)+,R3	;Restore R3
≠MOV≡≡SP≡≡R2≡≥	060634	012602				MOV	(SP)+,R2	;Restore R2
≠RTS≡≡RF≡≥	060636	000205				RTS	RF		;Return
≥					
≥					CHNGER:
≠COMMEN≡≥				COMMENT ⊗ Calls the change routine indicated.  This is done by
≥				instantiating a new interpreter to do the work.  It should terminate
≥				the normal way, with a TERMINATE command.  R2 points to the old
≥				value, and CHG.VNEW(RF) points to the new value.  R3 points to the
≥				changer cell.  These values are put into the new ISB.  GNODE
≥				exclusion should be released before the call to CHNGER.  Recall that
≥				a changer cell looks like this:
≥					XX  NXTCHG	;next changer cell in chain
≥					XX  CHGISB	;Points to interpreter status block to resolve addressing
≥					XX  CHGIPC	;the interpeter PC where the calculation starts
≥					⊗
≥					
≠MOV≡≡R2≡≡SP≡≥	060640	010246				MOV R2,-(SP)	;Save R2
≠MOV≡≡R3≡≡SP≡≥	060642	010346				MOV R3,-(SP)	;Save R3
≠MOV≡≡R4≡≡SP≡≥	060644	010446				MOV R4,-(SP)	;Save R4
≥					
≥						;make a new interpreter to do the work
≠MOV≡≡CHGISB≡≡R3≡≡R4≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 269
	GRAPHS PAL[HAL,HE]	PAGE 6.2 	Graph routines.

≥	060646	016304	000002			MOV CHGISB(R3),R4	;R4 ← ISB we have to emulate
≠MOV≡≡CHGIPC≡≡R3≡≡R0≡≥	060652	016300	000004			MOV CHGIPC(R3),R0	;R0 ← IPC of new ISB
≤EVMAK≡≥						EVMAK		;Stack a new event for communication with subsidiary
≥	060656	104004				104004
≠MOV≡≡SP≡≡R1≡≥	060660	011601				MOV (SP),R1	;R1 ← copy of that event
≠JSR≡≡PC≡≡SPAWN≡≥	060662	004767	757444			JSR PC,SPAWN	;R0 ← Process decriptor
≠MOV≡≡PDBR4≡≡R0≡≡R4≡≥	060666	016004	000036			MOV PDBR4(R0),R4;R4 ← ISB of new interpreter
≠MOV≡≡R2≡≡OLDV≡≡R4≡≥	060672	010264	000022			MOV R2,OLDV(R4)	;Stow the "old value" pointer in environment.
≠MOV≡≡CHG.VN≡≡RF≡≡NEWV≡≡R4≡≥	060676	016564	000002	000024		MOV CHG.VNEW(RF),NEWV(R4)	;Stow the "new value" pointer.
≤FORK≡≥						FORK R0,#INTERP,#2	;Cause the new process to be started at high prio.
≤.ARG≡≥						  .ARG #2
≠.LIF≡≥						    .LIF NB #2
≠MOV≡≡SP≡≥	060704	012746	000002			      MOV #2,-(SP)
≤.ARG≡≥						  .ARG #INTERP
≠.LIF≡≥						    .LIF NB #INTERP
≠MOV≡≡INTERP≡≡SP≡≥	060710	012746	036016			      MOV #INTERP,-(SP)
≤.ARG≡≥						  .ARG R0
≠.LIF≡≥						    .LIF NB R0
≠MOV≡≡R0≡≡SP≡≥	060714	010046				      MOV R0,-(SP)
≥	060716	104002				104002
≥					
≥						;clean up after the interpreter
≤EVWAIT≡≥						EVWAIT 		;Wait for the completion event (still on stack)
≤.ARG≡≥						  .ARG 
≠.LIF≡≥						    .LIF NB 
≥						      MOV ,-(SP)
≥	060720	104010				104010
≥					
≠MOV≡≡SP≡≡R4≡≥	060722	012604				MOV (SP)+,R4	;Restore R4
≠MOV≡≡SP≡≡R3≡≥	060724	012603				MOV (SP)+,R3	;Restore R3
≠MOV≡≡SP≡≡R2≡≥	060726	012602				MOV (SP)+,R2	;Restore R2
≠RTS≡≡PC≡≥	060730	000207				RTS PC		;Done
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 270
	GRAPHS PAL[HAL,HE]	PAGE 7 	Graph routines.

≥					;  ADDCHG
≥					
≤ROUTIN≡≥					ROUTINE ADDCHG,<ACH.ND,ACH.CHG>
≠.IFNB≡≥					           .IFNB ACH.ND,ACH.CHG
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<ACH.ND,ACH.CHG>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000004			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<ACH.ND,ACH.CHG>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡ACH.ND≡≥					                  .IFDF ACH.ND
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for ACH.ND
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡ACH.ND≠≥		000004			                   ACH.ND == NNNN
≡NNNN≡≡NNNN≠≥		000002			                   NNNN == NNNN-2
≠.IFDF≡≡ACH.CH≡≥					                  .IFDF ACH.CHG
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for ACH.CHG
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡ACH.CH≠≥		000002			                   ACH.CHG == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					ADDCHG:
≠COMMEN≡≥				COMMENT ⊗ ACH.ND is the target graph node, and ACH.CHG is a changer
≥				cell all prepared except for the link to the other changers.  It is
≥					necessary to perform this linking.  ⊗
≠MOV≡≡R2≡≡SP≡≥	060732	010246				MOV	R2,-(SP)	;Save R2
≠MOV≡≡ACH.ND≡≡RF≡≡R2≡≥	060734	016502	000004			MOV	ACH.ND(RF),R2	;R2 ← LOC[target node]
≠MOV≡≡ACH.CH≡≡RF≡≡R1≡≥	060740	016501	000002			MOV	ACH.CHG(RF),R1	;R1 ← LOC[changer cell]
≤EVWAIT≡≥						EVWAIT	GNEVT		;Enter critical region for graph nodes
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	060744	016746	777230			      MOV GNEVT,-(SP)
≥	060750	104010				104010
≠MOV≡≡VNCHGS≡≡R2≡≡NXTCHG≡≡R1≡≥	060752	016261	000020	000000		MOV	VNCHGS(R2),NXTCHG(R1) ;Link new changer into list
≠MOV≡≡R1≡≡VNCHGS≡≡R2≡≥	060760	010162	000020			MOV	R1,VNCHGS(R2)	;
≤EVSIG≡≥						EVSIG	GNEVT		;Leave critical region
≤.ARG≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 271
	GRAPHS PAL[HAL,HE]	PAGE 7.1 	Graph routines.

≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	060764	016746	777210			      MOV GNEVT,-(SP)
≥	060770	104012				104012
≠MOV≡≡SP≡≡R2≡≥	060772	012602				MOV	(SP)+,R2	;Restore R2
≠RTS≡≡R5≡≥	060774	000205				RTS	R5		;Done
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 272
	GRAPHS PAL[HAL,HE]	PAGE 8 	Graph routines.

≥					;  GETVAL, GETVR0
≥					
≠COMMEN≡≥				COMMENT ⊗ Called by the outside world.  Returns LOC[value(GTV.ND)] in
≥				R0 and the VALIDF in R1, after having scrounged around to get a valid
≥					value, if necessary and possible.  ⊗
≥					
≤ROUTIN≡≥					ROUTINE GETVAL,<GTV.ND>
≠.IFNB≡≥					           .IFNB GTV.ND
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<GTV.ND>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<GTV.ND>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡GTV.ND≡≥					                  .IFDF GTV.ND
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for GTV.ND
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡GTV.ND≠≥		000002			                   GTV.ND == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					GETVAL:
≠MOV≡≡GTV.ND≡≡RF≡≡R0≡≥	060776	016500	000002			MOV	GTV.ND(RF),R0
≠JSR≡≡PC≡≡GETVR0≡≥	061002	004767	000002			JSR	PC,GETVR0
≠RTS≡≡RF≡≥	061006	000205				RTS	RF
≥					
≠TST≡≡INVMRK≡≡R0≡≥	061010	005760	000006		GETVR0:	TST	INVMRK(R0)	;Is the current value good?
≠BEQ≡≥	061014	001422				BEQ	1$		;Yes
≤EVWAIT≡≥						EVWAIT	GNEVT		;No.  Enter critical region.
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	061016	016746	777156			      MOV GNEVT,-(SP)
≥	061022	104010				104010
≠MOV≡≡R0≡≡SP≡≥	061024	010046				MOV	R0,-(SP)	;Stack R0
≠MOV≡≡RF≡≡SP≡≥	061026	010546				MOV	RF,-(SP)
≠MOV≡≡R0≡≡SP≡≥	061030	010046				MOV	R0,-(SP)	;EVALNODE(GTV.ND,TIME←TIME+1)
≠JSR≡≡PC≡≡NXTTIM≡≥	061032	004767	777270			JSR	PC,NXTTIM	
≠MOV≡≡R0≡≡SP≡≥	061036	010046				MOV	R0,-(SP)
≠MOV≡≡MARK2≡≡SP≡≥	061040	012746	006402			MOV	#MARK2,-(SP)
≠MOV≡≡SP≡≡RF≡≥	061044	010605				MOV	SP,RF
≠JSR≡≡PC≡≡EVALND≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 273
	GRAPHS PAL[HAL,HE]	PAGE 8.1 	Graph routines.

≥	061046	004767	000022			JSR	PC,EVALND		
≤EVSIG≡≥						EVSIG	GNEVT		;Leave critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	061052	016746	777122			      MOV GNEVT,-(SP)
≥	061056	104012				104012
≠MOV≡≡SP≡≡R0≡≥	061060	012600				MOV	(SP)+,R0	;R0 ← target node, now validated
≠MOV≡≡VALIDF≡≡R0≡≡R1≡≥	061062	016001	000014		1$:	MOV	VALIDF(R0),R1	;Get the validity count
≠MOV≡≡GNVAL≡≡R0≡≡R0≡≥	061066	016000	000010			MOV	GNVAL(R0),R0	;R0 ← value cell
≠RTS≡≡PC≡≥	061072	000207				RTS	PC		;Done
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 274
	GRAPHS PAL[HAL,HE]	PAGE 9 	Graph routines.

≥					;  EVALND, EVLEXP
≥					
≠COMMEN≡≥				COMMENT ⊗ EVALND is a recursive procedure, which is given EVL.ND, the
≥				target node to evaluate, and EVL.T, the "time" of evaluation.  If
≥				necessary, it calls itself at the same "time" to track down a chain
≥				of related nodes.  GNEVT exclusion should be on before this routine
≥					is first called, and will remain on after the return. ⊗
≥					
≤ROUTIN≡≥					ROUTINE EVALND,<EVL.ND,EVL.T>
≠.IFNB≡≥					           .IFNB EVL.ND,EVL.T
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<EVL.ND,EVL.T>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000004			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<EVL.ND,EVL.T>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡EVL.ND≡≥					                  .IFDF EVL.ND
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for EVL.ND
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡EVL.ND≠≥		000004			                   EVL.ND == NNNN
≡NNNN≡≡NNNN≠≥		000002			                   NNNN == NNNN-2
≠.IFDF≡≡EVL.T≡≥					                  .IFDF EVL.T
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for EVL.T
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡EVL.T≠≥		000002			                   EVL.T == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					EVALND:
≠MOV≡≡EVL.ND≡≡RF≡≡R0≡≥	061074	016500	000004			MOV	EVL.ND(RF),R0	;R0 ← target graph node
≠MOV≡≡INVMRK≡≡R0≡≡R1≡≥	061100	016001	000006			MOV	INVMRK(R0),R1	;Is the node already valid?
≠BEQ≡≥	061104	001510				BEQ	9$		;Yes
≠CMP≡≡R1≡≡EVL.T≡≡RF≡≥	061106	020165	000002			CMP	R1,EVL.T(RF)	;No.  Have we already looked at it this "time"?
≠BEQ≡≥	061112	001505				BEQ	9$		;Yes
≠MOV≡≡EVL.T≡≡RF≡≡INVMRK≡≡R0≡≥	061114	016560	000002	000006		MOV	EVL.T(RF),INVMRK(R0)	;No. We have touched our node now
≠MOV≡≡R2≡≡SP≡≥	061122	010246				MOV	R2,-(SP)	;Save R2
≠MOV≡≡R3≡≡SP≡≥	061124	010346				MOV	R3,-(SP)	;Save R3
≠BIT≡≡GNMODE≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 275
	GRAPHS PAL[HAL,HE]	PAGE 9.1 	Graph routines.

≥	061126	032760	000001	000000		BIT	#1,GNMODE(R0)	;A variable or an expression?
≠BNE≡≥	061134	001012				BNE	1$		;Variable
≤CALL≡≥						CALL	EVLEXP,<R0,EVL.T(RF)>	;Sets GNVAL and INVMRK correctly
≠MOV≡≡RF≡≡SP≡≥	061136	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R0,EVL.T(RF)
≠.IRP≡≥						       .IRP II,<R0,EVL.T(RF)>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R0≡≡SP≡≥	061140	010046					MOV	R0,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡EVL.T≡≡RF≡≡SP≡≥	061142	016546	000002				MOV	EVL.T(RF),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	061146	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	061152	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡EVLEXP≡≥	061154	004767	000150			JSR	PC,EVLEXP		;Call the routine
≠BR≡≥	061160	000460				BR	8$		;Done
≥					
≥					1$:	;evaluate a variable.
≠MOV≡≡VNCLCS≡≡R0≡≡R2≡≥	061162	016002	000016			MOV	VNCLCS(R0),R2	;R2 ← list of calculator expressions
≠BEQ≡≥	061166	001455				BEQ	8$		;if any
≠MOV≡≡CAR≡≡R2≡≡R1≡≥	061170	016201	000000		2$:	MOV	CAR(R2),R1	;R1 ← first expression
≠TST≡≡INVMRK≡≡R1≡≥	061174	005761	000006			TST	INVMRK(R1)	;Is this expression valid?
≠BNE≡≥	061200	001004				BNE	3$		;No
≠MOV≡≡GNVAL≡≡R1≡≡GNVAL≡≡R0≡≥	061202	016160	000010	000010		MOV	GNVAL(R1),GNVAL(R0)	;Yes.  Copy its value pointer
≠BR≡≥	061210	000440				BR	7$		;Success exit.
≠MOV≡≡CDR≡≡R2≡≡R2≡≥	061212	016202	000002		3$:	MOV	CDR(R2),R2	;R2 ← rest of expression list
≠BNE≡≥	061216	001364				BNE	2$		;Try with next one.
≥					
≥						;no currently valid expression.  Try to evaluate one.
≠MOV≡≡VNCLCS≡≡R0≡≡R2≡≥	061220	016002	000016			MOV	VNCLCS(R0),R2	;R2 ← list of calculator expressions
≠BEQ≡≥	061224	001436				BEQ	8$		;if any
≠MOV≡≡CAR≡≡R2≡≡R1≡≥	061226	016201	000000		4$:	MOV	CAR(R2),R1	;R1 ← first expression
≤CALL≡≥						CALL	EVALND,<R1,EVL.T(RF)>
≠MOV≡≡RF≡≡SP≡≥	061232	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R1,EVL.T(RF)
≠.IRP≡≥						       .IRP II,<R1,EVL.T(RF)>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R1≡≡SP≡≥	061234	010146					MOV	R1,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡EVL.T≡≡RF≡≡SP≡≥	061236	016546	000002				MOV	EVL.T(RF),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	061242	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 276
	GRAPHS PAL[HAL,HE]	PAGE 9.2 	Graph routines.

≥	061246	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡EVALND≡≥	061250	004767	777620			JSR	PC,EVALND		;Call the routine
≠MOV≡≡CAR≡≡R2≡≡R1≡≥	061254	016201	000000			MOV	CAR(R2),R1	;
≠TST≡≡INVMRK≡≡R1≡≥	061260	005761	000006			TST	INVMRK(R1)	;Successfully evaluated?
≠BEQ≡≥	061264	001404				BEQ	5$		;Yes
≠MOV≡≡CDR≡≡R2≡≡R2≡≥	061266	016202	000002			MOV	CDR(R2),R2	;Try next one
≠BNE≡≥	061272	001355				BNE	4$		;If any
≠BR≡≥	061274	000412				BR	8$		;Give up
≠MOV≡≡EVL.ND≡≡RF≡≡R0≡≥	061276	016500	000004		5$:	MOV	EVL.ND(RF),R0	;
≠MOV≡≡GNVAL≡≡R1≡≡GNVAL≡≡R0≡≥	061302	016160	000010	000010		MOV	GNVAL(R1),GNVAL(R0)	;Transfer the value
≠BR≡≥	061310	000400				BR	7$		;Success return
≥					
≥					
≠COMMEN≡≥				COMMENT ⊗  Seems to be a relic here.
≥					;all the needs are met for the expression in CAR(R2)
≥					MOV	CAR(R2),R1	;R1 ← expression node
≥				6$:	CALL	EVALND,<R1,EVL.T(RF)>	;Evaluate the expression.
≥					MOV	EVL.ND(RF),R0	;R0 ← target node
≥					MOV	GNVAL(R1),GNVAL(R0)	;Stow away its new value.
≥					⊗
≥					
≠CLR≡≡INVMRK≡≡R0≡≥	061312	005060	000006		7$:	CLR	INVMRK(R0)	;Mark it as valid.
≠INC≡≡VALIDF≡≡R0≡≥	061316	005260	000014			INC	VALIDF(R0)	;Increment its validity number
≠MOV≡≡SP≡≡R3≡≥	061322	012603			8$:	MOV	(SP)+,R3	;Restore R3
≠MOV≡≡SP≡≡R2≡≥	061324	012602				MOV	(SP)+,R2	;Restore R2
≠RTS≡≡RF≡≥	061326	000205			9$:	RTS	RF		;Done
≥					
≠COMMEN≡≥				COMMENT ⊗ Each expression has a field, ENISB, which points to the
≥				interpreter status block of its definition.  This contains enough
≥				information to resolve any variable references in the expression.
≥				Calls the interpreter in a special way (through a CALL INTERP) having
≥				first set up a pseudo-ISB in R4.  When the interpreter returns, the
≥				desired value should be in R0.  Each time called, this routine
≥				constructs a new pseudo-ISB, uses it once, and then releases it.
≥				This is somewhat wasteful, and could be cleaned up.  The value found
≥				is put in the expression node, which is marked as valid.  It is not
≥				assumed that all the needed nodes have been validated before this
≥					routine is called.  ⊗
≥					
≤ROUTIN≡≥					ROUTINE EVLEXP,<EVE.EXP,EVE.T>
≠.IFNB≡≥					           .IFNB EVE.EXP,EVE.T
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<EVE.EXP,EVE.T>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000004			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<EVE.EXP,EVE.T>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 277
	GRAPHS PAL[HAL,HE]	PAGE 9.3 	Graph routines.

≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡EVE.EX≡≥					                  .IFDF EVE.EXP
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for EVE.EXP
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡EVE.EX≠≥		000004			                   EVE.EXP == NNNN
≡NNNN≡≡NNNN≠≥		000002			                   NNNN == NNNN-2
≠.IFDF≡≡EVE.T≡≥					                  .IFDF EVE.T
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for EVE.T
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡EVE.T≠≥		000002			                   EVE.T == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					EVLEXP:
≠MOV≡≡R2≡≡SP≡≥	061330	010246				MOV	R2,-(SP)	;Save R2
≠MOV≡≡R3≡≡SP≡≥	061332	010346				MOV	R3,-(SP)	;Save R3
≠MOV≡≡R4≡≡SP≡≥	061334	010446				MOV	R4,-(SP)	;Save R4
≥					
≥						;try to validate the needed list
≠MOV≡≡EVE.EX≡≡RF≡≡R0≡≥	061336	016500	000004			MOV	EVE.EXP(RF),R0	;R0 ← LOC[ENODE]
≠MOV≡≡EVE.T≡≡RF≡≡INVMRK≡≡R0≡≥	061342	016560	000002	000006		MOV	EVE.T(RF),INVMRK(R0)	;We are looking now.
≠MOV≡≡ENNEED≡≡R0≡≡R3≡≥	061350	016003	000020			MOV	ENNEED(R0),R3	;R3 ← needed list
≠BEQ≡≥	061354	001422				BEQ	2$		;if any
≤CALL≡≥					1$:	CALL	EVALND,<CAR(R3),EVE.T(RF)>	;Evaluate this need.
≠MOV≡≡RF≡≡SP≡≥	061356	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB CAR(R3),EVE.T(RF)
≠.IRP≡≥						       .IRP II,<CAR(R3),EVE.T(RF)>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡CAR≡≡R3≡≡SP≡≥	061360	016346	000000				MOV	CAR(R3),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡EVE.T≡≡RF≡≡SP≡≥	061364	016546	000002				MOV	EVE.T(RF),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	061370	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	061374	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡EVALND≡≥	061376	004767	777472			JSR	PC,EVALND		;Call the routine
≠MOV≡≡CAR≡≡R3≡≡R0≡≥	061402	016300	000000			MOV	CAR(R3),R0	;R0 ← variable node of the need
≠TST≡≡INVMRK≡≡R0≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 278
	GRAPHS PAL[HAL,HE]	PAGE 9.4 	Graph routines.

≥	061406	005760	000006			TST	INVMRK(R0)	;Is it now valid?
≠BNE≡≥	061412	001063				BNE	3$		;No, so we fail
≠MOV≡≡CDR≡≡R3≡≡R3≡≥	061414	016303	000002			MOV	CDR(R3),R3	;Yes.  R3 ← next needed cell
≠BNE≡≥	061420	001356				BNE	1$		;If any.
≥					
≥						;the needed list is ready
≠MOV≡≡ISBS≡≡R0≡≥	061422	012700	000017		2$:	MOV	#ISBS,R0	;Get a pseudo-ISB
≠JSR≡≡PC≡≡GTFREE≡≥	061426	004767	746614			JSR	PC,GTFREE	;R0 ← LOC[new ISB]
≠MOV≡≡R0≡≡R4≡≥	061432	010004				MOV	R0,R4		;R4 ← LOC[new ISB]
≠MOV≡≡EVE.EX≡≡RF≡≡R2≡≥	061434	016502	000004			MOV	EVE.EXP(RF),R2	;
≠MOV≡≡ENISB≡≡R2≡≡R1≡≥	061440	016201	000014			MOV	ENISB(R2),R1	;R1 ← LOC[old ISB]
≠MOV≡≡ENV≡≡R1≡≡ENV≡≡R4≡≥	061444	016164	000006	000006		MOV	ENV(R1),ENV(R4)	;Copy environments
≠MOV≡≡LEV≡≡R1≡≡LEV≡≡R4≡≥	061452	016164	000010	000010		MOV	LEV(R1),LEV(R4)	;Copy levels
≠MOV≡≡ENIPC≡≡R2≡≡IPC≡≡R4≡≥	061460	016264	000016	000000		MOV	ENIPC(R2),IPC(R4)	;Initialize the IPC
≠MOV≡≡INSTSZ≡≡R0≡≥	061466	012700	000020			MOV	#INSTSZ,R0	;
≠JSR≡≡PC≡≡GTFREE≡≥	061472	004767	746550			JSR	PC,GTFREE	;R0 ← LOC[new interpreter stack]
≠MOV≡≡R0≡≡SP≡≥	061476	010046				MOV	R0,-(SP)	;Save the stack location
≠ADD≡≡INSTSZ≡≡R0≡≥	061500	062700	000040			ADD	#2*INSTSZ,R0	;
≠MOV≡≡R0≡≡R3≡≥	061504	010003				MOV	R0,R3		;R3 ← LOC[verge of new interpreter stack]
≠JSR≡≡PC≡≡NOGC≡≥	061506	004767	751544		 	JSR	PC,NOGC		;Don't garbage collect during this.
≤CALL≡≥						CALL	INTERP		;Enter the interpreter, R0 ← LOC[new value cell]
≠MOV≡≡RF≡≡SP≡≥	061512	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB 
≥						       .IRP II,<>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	061514	012746	006400			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	061520	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡INTERP≡≥	061522	004767	754270			JSR	PC,INTERP		;Call the routine
≠MOV≡≡EVE.EX≡≡RF≡≡R2≡≥	061526	016502	000004			MOV	EVE.EXP(RF),R2	;R0 ← LOC[expression node]
≠CLR≡≡INVMRK≡≡R2≡≥	061532	005062	000006			CLR	INVMRK(R2)	;Now valid
≠MOV≡≡R0≡≡GNVAL≡≡R2≡≥	061536	010062	000010			MOV	R0,GNVAL(R2)	;Result into the node
≠MOV≡≡R4≡≡R0≡≥	061542	010400				MOV	R4,R0		;Release the ISB
≠JSR≡≡PC≡≡RLFREE≡≥	061544	004767	747040			JSR	PC,RLFREE	;
≠MOV≡≡SP≡≡R0≡≥	061550	012600				MOV	(SP)+,R0	;Release the interpreter stack
≠JSR≡≡PC≡≡RLFREE≡≥	061552	004767	747032			JSR	PC,RLFREE	;
≠JSR≡≡PC≡≡YESGC≡≥	061556	004767	751516			JSR	PC,YESGC	;Garbage collect ok now.
≠MOV≡≡SP≡≡R4≡≥	061562	012604			3$:	MOV	(SP)+,R4	;Restore R4
≠MOV≡≡SP≡≡R3≡≥	061564	012603				MOV	(SP)+,R3	;Restore R3
≠MOV≡≡SP≡≡R2≡≥	061566	012602				MOV	(SP)+,R2	;Restore R2
≠RTS≡≡RF≡≥	061570	000205				RTS	RF		;Return
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 279
	GRAPHS PAL[HAL,HE]	PAGE 10 	Graph routines.

≥					;  MAKEXP, ADDCLC, REMCLC, DELEXP
≥					
≤ROUTIN≡≥					ROUTINE ADDCLC,<ADD.VN,ADD.EN>
≠.IFNB≡≥					           .IFNB ADD.VN,ADD.EN
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<ADD.VN,ADD.EN>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000004			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<ADD.VN,ADD.EN>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡ADD.VN≡≥					                  .IFDF ADD.VN
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for ADD.VN
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡ADD.VN≠≥		000004			                   ADD.VN == NNNN
≡NNNN≡≡NNNN≠≥		000002			                   NNNN == NNNN-2
≠.IFDF≡≡ADD.EN≡≥					                  .IFDF ADD.EN
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for ADD.EN
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡ADD.EN≠≥		000002			                   ADD.EN == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					ADDCLC:
≠COMMEN≡≥				COMMENT ⊗ ADD.VN is the variable node, and ADD.EN is an expression
≥				node all prepared except for the link to the variable node.  This
≥					linking is performed.  ⊗
≥					⊗
≠MOV≡≡R2≡≡SP≡≥	061572	010246				MOV	R2,-(SP)	;Save R2
≠MOV≡≡R3≡≡SP≡≥	061574	010346				MOV	R3,-(SP)	;Save R3
≠MOV≡≡ADD.VN≡≡RF≡≡R2≡≥	061576	016502	000004			MOV	ADD.VN(RF),R2	;R2 ← LOC[variable node]
≠MOV≡≡ADD.EN≡≡RF≡≡R3≡≥	061602	016503	000002			MOV	ADD.EN(RF),R3	;R3 ← LOC[expression node]
≤EVWAIT≡≥						EVWAIT	GNEVT		;Enter critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	061606	016746	776366			      MOV GNEVT,-(SP)
≥	061612	104010				104010
≥						;Add the VNODE as a dependent of the ENODE
≠JSR≡≡PC≡≡NEWCEL≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 280
	GRAPHS PAL[HAL,HE]	PAGE 10.1 	Graph routines.

≥	061614	004767	776476			JSR	PC,NEWCEL	;R0 ← LOC[new cell]
≠MOV≡≡GNDEPS≡≡R3≡≡CDR≡≡R0≡≥	061620	016360	000012	000002		MOV	GNDEPS(R3),CDR(R0)
≠MOV≡≡R2≡≡CAR≡≡R0≡≥	061626	010260	000000			MOV	R2,CAR(R0)	;
≠MOV≡≡R0≡≡GNDEPS≡≡R3≡≥	061632	010063	000012			MOV	R0,GNDEPS(R3)	;
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	061636	016746	750046			      MOV SBEVT,-(SP)
≥	061642	104012				104012
≥					   .ENDC
≥						;Add the ENODE as an expression of the VNODE
≠JSR≡≡PC≡≡NEWCEL≡≥	061644	004767	776446			JSR	PC,NEWCEL	;R0 ← LOC[new cell]
≠MOV≡≡VNCLCS≡≡R2≡≡CDR≡≡R0≡≥	061650	016260	000016	000002		MOV	VNCLCS(R2),CDR(R0)
≠MOV≡≡R3≡≡CAR≡≡R0≡≥	061656	010360	000000			MOV	R3,CAR(R0)	;
≠MOV≡≡R0≡≡VNCLCS≡≡R2≡≥	061662	010062	000016			MOV	R0,VNCLCS(R2)	;
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	061666	016746	750016			      MOV SBEVT,-(SP)
≥	061672	104012				104012
≥					   .ENDC
≤EVSIG≡≥						EVSIG	GNEVT		;Leave critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	061674	016746	776300			      MOV GNEVT,-(SP)
≥	061700	104012				104012
≠MOV≡≡SP≡≡R3≡≥	061702	012603				MOV	(SP)+,R3	;Restore R3
≠MOV≡≡SP≡≡R2≡≥	061704	012602				MOV	(SP)+,R2	;Restore R2
≠RTS≡≡RF≡≥	061706	000205				RTS	RF		;Done
≥					
≤ROUTIN≡≥					ROUTINE MAKEXP,<MKE.ISB,MKE.IPC,MKE.NDS>
≠.IFNB≡≥					           .IFNB MKE.ISB,MKE.IPC,MKE.NDS
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<MKE.ISB,MKE.IPC,MKE.NDS>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000004			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000006			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<MKE.ISB,MKE.IPC,MKE.NDS>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 281
	GRAPHS PAL[HAL,HE]	PAGE 10.2 	Graph routines.

≥						       .ENDM
≠.IFDF≡≡MKE.IS≡≥					                  .IFDF MKE.ISB
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for MKE.ISB
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡MKE.IS≠≥		000006			                   MKE.ISB == NNNN
≡NNNN≡≡NNNN≠≥		000004			                   NNNN == NNNN-2
≠.IFDF≡≡MKE.IP≡≥					                  .IFDF MKE.IPC
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for MKE.IPC
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡MKE.IP≠≥		000004			                   MKE.IPC == NNNN
≡NNNN≡≡NNNN≠≥		000002			                   NNNN == NNNN-2
≠.IFDF≡≡MKE.ND≡≥					                  .IFDF MKE.NDS
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for MKE.NDS
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡MKE.ND≠≥		000002			                   MKE.NDS == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					MAKEXP:
≠COMMEN≡≥				COMMENT ⊗ Makes a new expression node with ENISB, ENIPC, ENNDS as
≥				specified.  Makes it a dependent of all the variables on the needed
≥					list.  ⊗
≥					
≠MOV≡≡R2≡≡SP≡≥	061710	010246				MOV R2,-(SP)		;Save R2
≠MOV≡≡R3≡≡SP≡≥	061712	010346				MOV R3,-(SP)		;Save R3
≠MOV≡≡ENDSIZ≡≡R0≡≥	061714	012700	000011			MOV #ENDSIZ,R0		;
≠JSR≡≡PC≡≡GTFREE≡≥	061720	004767	746322			JSR PC,GTFREE		;
≠MOV≡≡R0≡≡R3≡≥	061724	010003				MOV R0,R3		;R3 ← LOC[new expression node]
≠MOV≡≡GNMODE≡≡R3≡≥	061726	012763	000002	000000		MOV #2,GNMODE(R3)	;Expression
≠MOV≡≡INVMRK≡≡R3≡≥	061734	012763	777777	000006		MOV #-1,INVMRK(R3)	;Invalid
≠CLR≡≡GNVAL≡≡R3≡≥	061742	005063	000010			CLR GNVAL(R3)		;No value
≠CLR≡≡GNDEPS≡≡R3≡≥	061746	005063	000012			CLR GNDEPS(R3)		;No variable dependents
≠MOV≡≡MKE.IS≡≡RF≡≡ENISB≡≡R3≡≥	061752	016563	000006	000014		MOV MKE.ISB(RF),ENISB(R3)	;ISB
≠MOV≡≡MKE.IP≡≡RF≡≡ENIPC≡≡R3≡≥	061760	016563	000004	000016		MOV MKE.IPC(RF),ENIPC(R3)	;IPC
≠MOV≡≡MKE.ND≡≡RF≡≡R2≡≥	061766	016502	000002			MOV MKE.NDS(RF),R2	;Need list
≤EVWAIT≡≥						EVWAIT GNEVT		;Enter critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	061772	016746	776202			      MOV GNEVT,-(SP)
≥	061776	104010				104010
≠MOV≡≡R2≡≡ENNEED≡≡R3≡≥	062000	010263	000020			MOV R2,ENNEED(R3)	;
≥					
≥						;this expression is a dependent for each variable on the needed list.
≠BEQ≡≥	062004	001421				BEQ 2$			;If any
≠JSR≡≡PC≡≡NEWCEL≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 282
	GRAPHS PAL[HAL,HE]	PAGE 10.3 	Graph routines.

≥	062006	004767	776304		1$:	JSR PC,NEWCEL		;
≠MOV≡≡CAR≡≡R2≡≡R1≡≥	062012	016201	000000			MOV CAR(R2),R1		;R1 ← the next needed variable
≠MOV≡≡GNDEPS≡≡R1≡≡CDR≡≡R0≡≥	062016	016160	000012	000002		MOV GNDEPS(R1),CDR(R0)	;
≠MOV≡≡R3≡≡CAR≡≡R0≡≥	062024	010360	000000			MOV R3,CAR(R0)		;
≠MOV≡≡R0≡≡GNDEPS≡≡R1≡≥	062030	010061	000012			MOV R0,GNDEPS(R1)
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	062034	016746	747650			      MOV SBEVT,-(SP)
≥	062040	104012				104012
≥					   .ENDC
≠MOV≡≡CDR≡≡R2≡≡R2≡≥	062042	016202	000002			MOV CDR(R2),R2		;
≠BNE≡≥	062046	001357				BNE 1$			;Repeat
≥					
≥					2$:	;link up with all other graph nodes in the world
≠MOV≡≡GNODES≡≡R1≡≥	062050	016701	776116			MOV GNODES,R1		;
≠BEQ≡≥	062054	001404				BEQ 3$			;If any
≠MOV≡≡R1≡≡NXTGN≡≡R3≡≥	062056	010163	000002			MOV R1,NXTGN(R3)	;
≠MOV≡≡R3≡≡PRVGN≡≡R1≡≥	062062	010361	000004			MOV R3,PRVGN(R1)	;
≠MOV≡≡R3≡≡GNODES≡≥	062066	010367	776100		3$:	MOV R3,GNODES		;
≠MOV≡≡R3≡≡R0≡≥	062072	010300				MOV R3,R0		;R0 ← LOC[new expression node]
≤EVSIG≡≥						EVSIG GNEVT		;Leave critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	062074	016746	776100			      MOV GNEVT,-(SP)
≥	062100	104012				104012
≠MOV≡≡SP≡≡R3≡≥	062102	012603				MOV (SP)+,R3		;Restore R3
≠MOV≡≡SP≡≡R2≡≥	062104	012602				MOV (SP)+,R2		;Restore R2
≠RTS≡≡RF≡≥	062106	000205				RTS RF			;Done
≥					
≤ROUTIN≡≥					ROUTINE REMCLC,<RMC.VN,RMC.EN>
≠.IFNB≡≥					           .IFNB RMC.VN,RMC.EN
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<RMC.VN,RMC.EN>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≡NNNN≡≡NNNN≠≥		000004			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<RMC.VN,RMC.EN>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡RMC.VN≡≥					                  .IFDF RMC.VN
≠.IF1≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 283
	GRAPHS PAL[HAL,HE]	PAGE 10.4 	Graph routines.

≥					                      .IF1 
≥					                           .ERROR Multiple definition for RMC.VN
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡RMC.VN≠≥		000004			                   RMC.VN == NNNN
≡NNNN≡≡NNNN≠≥		000002			                   NNNN == NNNN-2
≠.IFDF≡≡RMC.EN≡≥					                  .IFDF RMC.EN
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for RMC.EN
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡RMC.EN≠≥		000002			                   RMC.EN == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					REMCLC:
≠COMMEN≡≥					COMMENT ⊗ Unlinks the given expression from the given variable.  ⊗
≠MOV≡≡R2≡≡SP≡≥	062110	010246				MOV R2,-(SP)		;Save R2
≠MOV≡≡R3≡≡SP≡≥	062112	010346				MOV R3,-(SP)		;Save R3
≠MOV≡≡RMC.EN≡≡RF≡≡R2≡≥	062114	016502	000002			MOV RMC.EN(RF),R2	;R2 ← ENODE
≠MOV≡≡RMC.VN≡≡RF≡≡R3≡≥	062120	016503	000004			MOV RMC.VN(RF),R3	;R3 ← VNODE
≤CALL≡≥						CALL GETVAL,<R3>	;Make sure he has a last chance to get value.
≠MOV≡≡RF≡≡SP≡≥	062124	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R3
≠.IRP≡≥						       .IRP II,<R3>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R3≡≡SP≡≥	062126	010346					MOV	R3,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	062130	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	062134	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡GETVAL≡≥	062136	004767	776634			JSR	PC,GETVAL		;Call the routine
≤EVSIG≡≥						EVSIG GNEVT		;Enter critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	062142	016746	776032			      MOV GNEVT,-(SP)
≥	062146	104012				104012
≥						;remove the VNODE as a dependent of the ENODE
≠MOV≡≡GNDEPS≡≡R2≡≡R0≡≥	062150	016200	000012			MOV GNDEPS(R2),R0	;
≠MOV≡≡R3≡≡R1≡≥	062154	010301				MOV R3,R1		;
≠JSR≡≡PC≡≡UNLINK≡≥	062156	004767	776046			JSR PC,UNLINK		;
≠MOV≡≡R0≡≡GNDEPS≡≡R2≡≥	062162	010062	000012			MOV R0,GNDEPS(R2)	;
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	062166	016746	747516			      MOV SBEVT,-(SP)
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 284
	GRAPHS PAL[HAL,HE]	PAGE 10.5 	Graph routines.

≥	062172	104012				104012
≥					   .ENDC
≥						;remove the ENODE as a calculator of the VNODE
≠MOV≡≡VNCLCS≡≡R3≡≡R0≡≥	062174	016300	000016			MOV VNCLCS(R3),R0	;
≠MOV≡≡R2≡≡R1≡≥	062200	010201				MOV R2,R1		;
≠JSR≡≡PC≡≡UNLINK≡≥	062202	004767	776022			JSR PC,UNLINK		;
≠MOV≡≡R0≡≡VNCLCS≡≡R3≡≥	062206	010063	000016			MOV R0,VNCLCS(R3)	;
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	062212	016746	747472			      MOV SBEVT,-(SP)
≥	062216	104012				104012
≥					   .ENDC
≤EVSIG≡≥						EVSIG GNEVT		;Leave critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	062220	016746	775754			      MOV GNEVT,-(SP)
≥	062224	104012				104012
≠MOV≡≡SP≡≡R3≡≥	062226	012603				MOV (SP)+,R3		;Restore R3
≠MOV≡≡SP≡≡R2≡≥	062230	012602				MOV (SP)+,R2		;Restore R2
≠RTS≡≡RF≡≥	062232	000205				RTS RF			;Done
≥					
≤ROUTIN≡≥					ROUTINE DELEXP,<DLE.EN>
≠.IFNB≡≥					           .IFNB DLE.EN
≡NNNN≠≥		000000				    NNNN==0
≠.IRP≡≥						       .IRP II,<DLE.EN>		;Raise NNNN to twice the number of args.
≥					                   NNNN==NNNN+2
≥						       .ENDM
≡NNNN≡≡NNNN≠≥		000002			                   NNNN==NNNN+2
≠.IRP≡≥						       .IRP II,<DLE.EN>		;Assign each arg NNNN and decrease same.
≥					                  .IFDF II
≥					                      .IF1 
≥					                           .ERROR Multiple definition for II
≥					                      .ENDC
≥					                  .ENDC
≥					                   II == NNNN
≥					                   NNNN == NNNN-2
≥						       .ENDM
≠.IFDF≡≡DLE.EN≡≥					                  .IFDF DLE.EN
≠.IF1≡≥					                      .IF1 
≥					                           .ERROR Multiple definition for DLE.EN
≥					                      .ENDC
≥					                  .ENDC
≡NNNN≡≡DLE.EN≠≥		000002			                   DLE.EN == NNNN
≡NNNN≡≡NNNN≠≥		000000			                   NNNN == NNNN-2
≥						   .ENDC
≥					DELEXP:
≠COMMEN≡≥				COMMENT ⊗ Must remove this expression from all variable nodes which
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 285
	GRAPHS PAL[HAL,HE]	PAGE 10.6 	Graph routines.

≥				are dependent on it, having tried to validate them.  Then unlink the
≥					expression node and reclaim it. modified 10/76 by arg ⊗
≠MOV≡≡R2≡≡SP≡≥	062234	010246				MOV R2,-(SP)		;Save R2
≠MOV≡≡R3≡≡SP≡≥	062236	010346				MOV R3,-(SP)		;Save R3
≠MOV≡≡DLE.EN≡≡RF≡≡R2≡≥	062240	016502	000002			MOV DLE.EN(RF),R2	;R2 ← LOC[victim expression node]
≤EVWAIT≡≥						EVWAIT GNEVT		;Enter critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	062244	016746	775730			      MOV GNEVT,-(SP)
≥	062250	104010				104010
≠MOV≡≡GNDEPS≡≡R2≡≡R3≡≥	062252	016203	000012			MOV GNDEPS(R2),R3	;R3 ← list of dependents
≠BEQ≡≥	062256	001436				BEQ 2$			;If any
≠JSR≡≡PC≡≡NXTTIM≡≥	062260	004767	776042			JSR PC,NXTTIM		;
≠MOV≡≡R0≡≡SP≡≥	062264	010046				MOV R0,-(SP)		;New time for the evaluations to follow
≠MOV≡≡CAR≡≡R3≡≡R0≡≥	062266	016300	000000		1$:	MOV CAR(R3),R0		;
≠MOV≡≡SP≡≡R1≡≥	062272	011601				MOV (SP),R1		;Time
≤CALL≡≥						CALL EVALND,<R0,R1>	;Try to validate him
≠MOV≡≡RF≡≡SP≡≥	062274	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R0,R1
≠.IRP≡≥						       .IRP II,<R0,R1>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R0≡≡SP≡≥	062276	010046					MOV	R0,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≠MOV≡≡R1≡≡SP≡≥	062300	010146					MOV	R1,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006402					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	062302	012746	006402			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	062306	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡EVALND≡≥	062310	004767	776560			JSR	PC,EVALND		;Call the routine
≠MOV≡≡VNCLCS≡≡R0≡≡R0≡≥	062314	016000	000016			MOV VNCLCS(R0),R0	;R0 ← his list of calculators
≠MOV≡≡R2≡≡R1≡≥	062320	010201				MOV R2,R1		;us
≠JSR≡≡PC≡≡UNLINK≡≥	062322	004767	775702			JSR PC,UNLINK		;Remove us from that list
≠MOV≡≡CAR≡≡R3≡≡R1≡≥	062326	016301	000000			MOV CAR(R3),R1		;him
≠MOV≡≡R0≡≡VNCLCS≡≡R1≡≥	062332	010061	000016			MOV R0,VNCLCS(R1)	;Put back his calculator list, minus us.
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	062336	016746	747346			      MOV SBEVT,-(SP)
≥	062342	104012				104012
≥					   .ENDC
≠MOV≡≡CDR≡≡R3≡≡R3≡≥	062344	016303	000002			MOV CDR(R3),R3		;Next calculator
≠BNE≡≥	062350	001346				BNE 1$			;If any
≠TST≡≡SP≡≥	062352	005726				TST (SP)+		;Clear the time from the stack
≥					
≥						;Remove the expression from the dependent list's of all the variables
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 286
	GRAPHS PAL[HAL,HE]	PAGE 10.7 	Graph routines.

≥						;on the expressions needed list
≠MOV≡≡ENNEED≡≡R2≡≡R3≡≥	062354	016203	000020		2$:	MOV ENNEED(R2),R3	;Get needed list
≠BEQ≡≥	062360	001421				BEQ 4$			;If any
≠MOV≡≡CAR≡≡R3≡≡R0≡≥	062362	016300	000000		3$:	MOV CAR(R3),R0		;R0 ← variable from needed list
≠MOV≡≡GNDEPS≡≡R0≡≡R0≡≥	062366	016000	000012			MOV GNDEPS(R0),R0	;R0 ← his list of dependents
≠MOV≡≡R2≡≡R1≡≥	062372	010201				MOV R2,R1		;us
≠JSR≡≡PC≡≡UNLINK≡≥	062374	004767	775630			JSR PC,UNLINK		;Remove us from his list
≠MOV≡≡CAR≡≡R3≡≡R1≡≥	062400	016301	000000			MOV CAR(R3),R1		;him again
≠MOV≡≡R0≡≡GNDEPS≡≡R1≡≥	062404	010061	000012			MOV R0,GNDEPS(R1)	;Put back his dependent list minus us
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	062410	016746	747274			      MOV SBEVT,-(SP)
≥	062414	104012				104012
≥					   .ENDC
≠MOV≡≡CDR≡≡R3≡≡R3≡≥	062416	016303	000002			MOV CDR(R3),R3		;Next from needed list
≠BNE≡≥	062422	001357				BNE 3$			;Til done
≥					
≥						;unlink this expression node
≠MOV≡≡NXTGN≡≡R2≡≡R1≡≥	062424	016201	000002		4$:	MOV NXTGN(R2),R1	;R1 ← forward link
≠MOV≡≡PRVGN≡≡R2≡≡R0≡≥	062430	016200	000004			MOV PRVGN(R2),R0	;R0 ← backward link
≠MOV≡≡R0≡≡PRVGN≡≡R1≡≥	062434	010061	000004			MOV R0,PRVGN(R1)	;
≠MOV≡≡R1≡≡NXTGN≡≡R0≡≥	062440	010160	000002			MOV R1,NXTGN(R0)	;
≠MOV≡≡R2≡≡R0≡≥	062444	010200				MOV R2,R0
≠JSR≡≡PC≡≡RLFREE≡≥	062446	004767	746136			JSR PC,RLFREE		;Release the space
≤EVSIG≡≥						EVSIG GNEVT		;Leave critical region.
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	062452	016746	775522			      MOV GNEVT,-(SP)
≥	062456	104012				104012
≠MOV≡≡SP≡≡R3≡≥	062460	012603				MOV (SP)+,R3		;Restore R3
≠MOV≡≡SP≡≡R2≡≥	062462	012602				MOV (SP)+,R2		;Restore R2
≠RTS≡≡RF≡≥	062464	000205				RTS RF			;Done
≥						
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 287
	GRAPHS PAL[HAL,HE]	PAGE 11 	Graph routines.

≥					;  MAKEVN, DELVN
≥					
≥					MAKEVN:
≠COMMEN≡≥				COMMENT ⊗ Creates a variable node, with no frills (no calculators,
≥				changers, loksh, boydem, tsibele, ...) except that if R0 is
≥				non-zero, that is assumed to be the value cell pointer.  The node
≥				will be marked as invalid unless there was some value given.  The
≥				space is taken from large block storage.  The new variable node is
≥					returned in R0.  ⊗
≥					
≠MOV≡≡R0≡≡SP≡≥	062466	010046				MOV R0,-(SP)		;Save R0
≠MOV≡≡VNDSIZ≡≡R0≡≥	062470	012700	000011			MOV #VNDSIZ,R0
≠JSR≡≡PC≡≡GTFREE≡≥	062474	004767	745546			JSR PC,GTFREE		;R0 ← LOC[new graph node]
≠CLR≡≡INVMRK≡≡R0≡≥	062500	005060	000006			CLR INVMRK(R0)		;Validate the node
≠MOV≡≡GNMODE≡≡R0≡≥	062504	012760	000001	000000		MOV #1,GNMODE(R0)	;Variable, not expression
≠MOV≡≡SP≡≡GNVAL≡≡R0≡≥	062512	012660	000010			MOV (SP)+,GNVAL(R0)	;Stuff away the value cell pointer.
≠BNE≡≥	062516	001003				BNE 1$			;Was there one?
≠MOV≡≡INVMRK≡≡R0≡≥	062520	012760	777777	000006		MOV #-1,INVMRK(R0)	;No. Invalidate this node.
≠CLR≡≡GNDEPS≡≡R0≡≥	062526	005060	000012		1$:	CLR GNDEPS(R0)		;Zero other fields
≠CLR≡≡VNCLCS≡≡R0≡≥	062532	005060	000016			CLR VNCLCS(R0)	
≠CLR≡≡VNCHGS≡≡R0≡≥	062536	005060	000020			CLR VNCHGS(R0)
≠CLR≡≡NXTGN≡≡R0≡≥	062542	005060	000002			CLR NXTGN(R0)
≠CLR≡≡PRVGN≡≡R0≡≥	062546	005060	000004			CLR PRVGN(R0)
≠CLR≡≡VALIDF≡≡R0≡≥	062552	005060	000014			CLR VALIDF(R0)
≤EVWAIT≡≥						EVWAIT GNEVT		;Critical section here
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	062556	016746	775416			      MOV GNEVT,-(SP)
≥	062562	104010				104010
≠MOV≡≡GNODES≡≡R1≡≥	062564	016701	775402			MOV GNODES,R1		;Link up to other nodes in the world.
≠BEQ≡≥	062570	001404				BEQ 2$			;If any
≠MOV≡≡R1≡≡NXTGN≡≡R0≡≥	062572	010160	000002			MOV R1,NXTGN(R0)
≠MOV≡≡R0≡≡PRVGN≡≡R1≡≥	062576	010061	000004			MOV R0,PRVGN(R1)
≠MOV≡≡R0≡≡GNODES≡≥	062602	010067	775364		2$:	MOV R0,GNODES	
≤EVSIG≡≥						EVSIG GNEVT		;End of critical section
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	062606	016746	775366			      MOV GNEVT,-(SP)
≥	062612	104012				104012
≠RTS≡≡PC≡≥	062614	000207				RTS PC
≥					
≥					DELVN:
≠COMMEN≡≥				COMMENT ⊗ R0 is the location of the variable node.  All dependent
≥				expressions are first validated if possible, then those are deleted.
≥				(Not any more. arg 10/76)
≥				The value cell and all cell lists (like GNDEPS, VNCLCS) are reclaimed
≥				by relying on the garbage colector.  Thus graph nodes may share value
≥				cells.  The changer list is explicitly released, so changer lists may
≥				not be shared.  Then the node itself is unlinked from the chain and
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 288
	GRAPHS PAL[HAL,HE]	PAGE 11.1 	Graph routines.

≥					returned to free storage. ⊗
≥					
≠MOV≡≡R2≡≡SP≡≥	062616	010246				MOV R2,-(SP)		;Save R2
≠MOV≡≡R3≡≡SP≡≥	062620	010346				MOV R3,-(SP)		;Save R3
≠MOV≡≡R0≡≡R2≡≥	062622	010002				MOV R0,R2		;R2 ← variable node to delete
≥					
≥						;Try to validate the dependents
≠MOV≡≡GNDEPS≡≡R2≡≡R3≡≥	062624	016203	000012			MOV GNDEPS(R2),R3	;R3 ← List of dependent expressions
≠BEQ≡≥	062630	001413				BEQ 2$			;if any
≤CALL≡≥					1$:	CALL DELEXP,<CAR(R3)>	;Delete expression.
≠MOV≡≡RF≡≡SP≡≥	062632	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB CAR(R3)
≠.IRP≡≥						       .IRP II,<CAR(R3)>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡CAR≡≡R3≡≡SP≡≥	062634	016346	000000				MOV	CAR(R3),-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	062640	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	062644	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡DELEXP≡≥	062646	004767	777362			JSR	PC,DELEXP		;Call the routine
≠MOV≡≡CDR≡≡R3≡≡R3≡≥	062652	016303	000002			MOV CDR(R3),R3		;R3 ← next dependent
≠BNE≡≥	062656	001365				BNE 1$			;if any
≥					
≥						;Tell each calculator expression that we are no longer dependent
≤EVWAIT≡≥					2$:	EVWAIT GNEVT		;Enter critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	062660	016746	775314			      MOV GNEVT,-(SP)
≥	062664	104010				104010
≠MOV≡≡VNCLCS≡≡R2≡≡R3≡≥	062666	016203	000016			MOV VNCLCS(R2),R3	;R3 ← List of calculator expressions
≠BEQ≡≥	062672	001431				BEQ 5$			;If any
≠MOV≡≡CAR≡≡R3≡≡R0≡≥	062674	016300	000000		3$:	MOV CAR(R3),R0		;
≠MOV≡≡GNDEPS≡≡R0≡≡R0≡≥	062700	016000	000012			MOV GNDEPS(R0),R0	;R0 ← that expression's dependent list
≠MOV≡≡R2≡≡R1≡≥	062704	010201				MOV R2,R1		;R1 ← us
≠JSR≡≡PC≡≡UNLINK≡≥	062706	004767	775316			JSR PC,UNLINK		;Remove us from his dependent list
≠MOV≡≡CAR≡≡R3≡≡R1≡≥	062712	016301	000000			MOV CAR(R3),R1		;R1 ← him
≠MOV≡≡R0≡≡GNDEPS≡≡R1≡≥	062716	010061	000012			MOV R0,GNDEPS(R1)	;Replace his new dependent list
≠.IFNZ≡≡SMALLB≡≥		000001			   .IFNZ SMALLB
≤EVSIG≡≥						EVSIG SBEVT	;End of critical section - value stored
≤.ARG≡≥						  .ARG SBEVT
≠.LIF≡≥						    .LIF NB SBEVT
≠MOV≡≡SBEVT≡≡SP≡≥	062722	016746	746762			      MOV SBEVT,-(SP)
≥	062726	104012				104012
≥					   .ENDC
≠BNE≡≥	062730	001007				BNE 4$
≤CALL≡≥						CALL DELEXP,<R1>	;Delete expression if no one else dependent on him
≠MOV≡≡RF≡≡SP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 289
	GRAPHS PAL[HAL,HE]	PAGE 11.2 	Graph routines.

≥	062732	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB R1
≠.IRP≡≥						       .IRP II,<R1>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≠MOV≡≡R1≡≡SP≡≥	062734	010146					MOV	R1,-(SP);Push an argument
≡NNNN≡≡NNNN≠≥		006401					NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	062736	012746	006401			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	062742	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡DELEXP≡≥	062744	004767	777264			JSR	PC,DELEXP		;Call the routine
≠MOV≡≡CDR≡≡R3≡≡R3≡≥	062750	016303	000002		4$:	MOV CDR(R3),R3		;Do the same for the other calculator expressions
≠BNE≡≥	062754	001347				BNE 3$			;If any
≥					
≥						;Reclaim the changer cells
≠MOV≡≡VNCHGS≡≡R2≡≡R3≡≥	062756	016203	000020		5$:	MOV VNCHGS(R2),R3	;R3 ← First changer cell
≠MOV≡≡R3≡≡R0≡≥	062762	010300			6$::	MOV R3,R0		;R0 ← current changer cell
≠BEQ≡≥	062764	001405				BEQ 7$			;If any
≠MOV≡≡NXTCHG≡≡R3≡≡R3≡≥	062766	016303	000000			MOV NXTCHG(R3),R3	;R3 ← next changer cell
≠JSR≡≡PC≡≡RLFREE≡≥	062772	004767	745612			JSR PC,RLFREE		;Release current one
≠BR≡≥	062776	000771				BR  6$			;Do the others
≥					
≥						;Unlink this graph node
≠MOV≡≡NXTGN≡≡R2≡≡R1≡≥	063000	016201	000002		7$:	MOV NXTGN(R2),R1	;R1 ← forward link
≠MOV≡≡PRVGN≡≡R2≡≡R0≡≥	063004	016200	000004			MOV PRVGN(R2),R0	;R0 ← backward link
≠BEQ≡≥	063010	001403				BEQ 8$			;if any
≠MOV≡≡R1≡≡NXTGN≡≡R0≡≥	063012	010160	000002			MOV R1,NXTGN(R0)	;
≠BR≡≥	063016	000402				BR 9$			;
≠MOV≡≡R1≡≡GNODES≡≥	063020	010167	775146		8$:	MOV R1,GNODES		;if no backward link, then the header.
≠TST≡≡R1≡≥	063024	005701			9$:	TST R1			;Is there a forward link?
≠BEQ≡≥	063026	001402				BEQ 10$			;No
≠MOV≡≡R0≡≡PRVGN≡≡R1≡≥	063030	010061	000004			MOV R0,PRVGN(R1)	;Yes.  set up next guy's backpointer
≤EVSIG≡≥					10$:	EVSIG GNEVT		;Leave critical region.
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	063034	016746	775140			      MOV GNEVT,-(SP)
≥	063040	104012				104012
≥					
≠MOV≡≡R2≡≡R0≡≥	063042	010200				MOV R2,R0		;R0 ← target graph node hulk
≠JSR≡≡PC≡≡RLFREE≡≥	063044	004767	745540			JSR PC,RLFREE		;Release it.
≠MOV≡≡SP≡≡R3≡≥	063050	012603				MOV (SP)+,R3		;Restore R3
≠MOV≡≡SP≡≡R2≡≥	063052	012602				MOV (SP)+,R2		;Restore R2
≠RTS≡≡PC≡≥	063054	000207				RTS PC			;Done
≥					
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 290
	GRAPHS PAL[HAL,HE]	PAGE 12 	Graph routines.

≥					;  MGNDS  marking method for gnodes
≥					
≥					MGNDS:	;Marking method for GNODES
≠MOV≡≡R2≡≡SP≡≥	063056	010246				MOV R2,-(SP)		;Save R2
≤EVWAIT≡≥						EVWAIT GNEVT		;Enter critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	063060	016746	775114			      MOV GNEVT,-(SP)
≥	063064	104010				104010
≠MOV≡≡GNODES≡≡R2≡≥	063066	016702	775100			MOV GNODES,R2		;R2 ← LOC[first graph node]
≠BEQ≡≥	063072	001446				BEQ 4$			;If none, then done
≠TST≡≡INVMRK≡≡R2≡≥	063074	005762	000006		1$:	TST INVMRK(R2)		;See if value is valid
≠BEQ≡≥	063100	001403				BEQ 5$
≠CLR≡≡GNVAL≡≡R2≡≥	063102	005062	000010			CLR GNVAL(R2)		; & if so don't mark it
≠BR≡≥	063106	000406				BR  6$
≠MOV≡≡GNVAL≡≡R2≡≡R0≡≥	063110	016200	000010		5$:	MOV GNVAL(R2),R0	;Mark the value cell
≠JSR≡≡PC≡≡MARKQ≡≥	063114	004767	752146			JSR PC,MARKQ		;
≠MOV≡≡R0≡≡GNVAL≡≡R2≡≥	063120	010062	000010			MOV R0,GNVAL(R2)	;Put it back (compactification may move it)
≠MOV≡≡GNDEPS≡≡R2≡≡R0≡≥	063124	016200	000012		6$:	MOV GNDEPS(R2),R0	;Mark the cells used in the dependent list
≠JSR≡≡PC≡≡MCELL≡≥	063130	004767	752070			JSR PC,MCELL		;
≠MOV≡≡R0≡≡GNDEPS≡≡R2≡≥	063134	010062	000012			MOV R0,GNDEPS(R2)	;Put it back
≠BIT≡≡GNMODE≡≡R2≡≥	063140	032762	000001	000000		BIT #1,GNMODE(R2)	;What kind of graph node is it?
≠BEQ≡≥	063146	001407				BEQ 2$
≠MOV≡≡VNCLCS≡≡R2≡≡R0≡≥	063150	016200	000016			MOV VNCLCS(R2),R0	;A variable.  Mark cells in CLC list
≠JSR≡≡PC≡≡MCELL≡≥	063154	004767	752044			JSR PC,MCELL		;
≠MOV≡≡R0≡≡VNCLCS≡≡R2≡≥	063160	010062	000016			MOV R0,VNCLCS(R2)	;Put it back
≠BR≡≥	063164	000406				BR  3$
≠MOV≡≡ENNEED≡≡R2≡≡R0≡≥	063166	016200	000020		2$:	MOV ENNEED(R2),R0	;An expression.   Mark cells in ENNEED list
≠JSR≡≡PC≡≡MCELL≡≥	063172	004767	752026			JSR PC,MCELL		;
≠MOV≡≡R0≡≡ENNEED≡≡R2≡≥	063176	010062	000020			MOV R0,ENNEED(R2)	;Put it back
≠MOV≡≡NXTGN≡≡R2≡≡R2≡≥	063202	016202	000002		3$:	MOV NXTGN(R2),R2	;R2 ← LOC[next graph node]
≠BNE≡≥	063206	001332				BNE 1$			;Repeat as necessary
≠MOV≡≡SP≡≡R2≡≥	063210	012602			4$:	MOV (SP)+,R2		;Restore R2
≤EVSIG≡≥						EVSIG GNEVT		;Leave critical region
≤.ARG≡≥						  .ARG GNEVT
≠.LIF≡≥						    .LIF NB GNEVT
≠MOV≡≡GNEVT≡≡SP≡≥	063212	016746	774762			      MOV GNEVT,-(SP)
≥	063216	104012				104012
≠RTS≡≡RF≡≥	063220	000205				RTS RF			;Return
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 291
	GRAPHS PAL[HAL,HE]	PAGE 13 	Graph routines.

≥					;  Known Bugs
≥					
≠COMMEN≡≥				COMMENT ⊗ It is possible that while a graph node is changed, a
≥				changer is invoked.  During its execution, some other process
≥				modifies the change list for that node.  When the changer is done, it
≥				may get lost in the changer cell list.  Graph node exclusion must be
≥				turned off during execution of a changer, so that it can change other
≥				cells.  Special changer exclusion causes deadlock in the case that
≥				one changer triggers another.  
≥				
≥				Certain variables, like YELLOW and BLUE, are not being initialized
≥				to anything.
≥				
≥					⊗
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 292
	HAL PAL[HAL,HE]	PAGE 2.7 	Graph routines.

≥					.ENDC
≥					
≥					
≠.IFNZ≡≡DETECT≡≥		000000			.IFNZ DETECT		;Collision detector
≥					    .INSRT DETECT.PAL[HAL,HE]
≥					.ENDC
≥					
≥					;Data areas
≥					
≠.BLKW≡≡ISBS≡≥		063260			ISTBLK:	.BLKW ISBS	;Dummy interpreter status block (used in linking only)
≡ENVLTH≠≥		000200			ENVLTH == 200
≠.BLKW≡≡ENVLTH≡≥		063660			ENVIRO:	.BLKW ENVLTH	;Environment
≥					
≤PUTLOC≡≥						PUTLOC JOBDAT, MAINBL
≡II≠≥		063660			        II==.
≡JOBDAT≡≥		013774			        .= JOBDAT
≡MAINBL≡≡MAINBL≡≥	013774	031170			         MAINBL
≡II≡≥		063660			       .=II
≤PUTLOC≡≥						PUTLOC JOBSA, START
≡II≠≥		063660			        II==.
≡JOBSA≡≥		013776			        .= JOBSA
≡START≡≡START≡≥	013776	063660			         START
≡II≡≥		063660			       .=II
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 293
	HAL PAL[HAL,HE]	PAGE 3 	Graph routines.

≥					; program initialization
≥					
≥					START:	
≥						;initialize the world
≠JSR≡≡PC≡≡FRINIT≡≥	063660	004767	744234			JSR PC,FRINIT	;Initialize free storage
≠.IFNZ≡≡SMALLB≡≥		000001			    .IFNZ SMALLB
≤CALL≡≥						CALL SBINIT	;Initialize small block space
≠MOV≡≡RF≡≡SP≡≥	063664	010546				MOV	RF,-(SP)	;Save RF
≡NNNN≠≥		006400				NNNN == 6400		;This is a MARK 0 instruction
≠.IFNB≡≥						   .IFNB 
≥						       .IRP II,<>
≥							MOV	II,-(SP);Push an argument
≥							NNNN == NNNN+1	;Make NNNN the next MARK instruction.
≥						       .ENDM
≥						   .ENDC
≠MOV≡≡NNNN≡≡SP≡≥	063666	012746	006400			MOV	#NNNN,-(SP)	;Push the mark instruction.
≠MOV≡≡SP≡≡RF≡≥	063672	010605				MOV	SP,RF		;Set up the display in RF.
≠JSR≡≡PC≡≡SBINIT≡≥	063674	004767	751202			JSR	PC,SBINIT		;Call the routine
≥					    .ENDC
≠.IFNZ≡≡GRAPHS≡≥		000001			    .IFNZ GRAPHS
≠JSR≡≡PC≡≡GSINIT≡≥	063700	004767	774276			JSR PC,GSINIT	;Initialize graph structure
≥					    .ENDC
≠.IFNZ≡≡MOVING≡≥		000001			    .IFNZ MOVING
≠MOV≡≡R0≡≥	063704	012700	000034			MOV #34,R0	;Get a device block
≠JSR≡≡PC≡≡GTFREE≡≥	063710	004767	744332			JSR PC,GTFREE	;
≠MOV≡≡R0≡≡R1≡≥	063714	010001				MOV R0,R1
≠MOV≡≡R0≡≡SP≡≥	063716	010046				MOV R0,-(SP)	;Save address of device block so we can free it
≠JSR≡≡PC≡≡LINTAR≡≥	063720	004777	730070			JSR PC,@LINTARM	;Initialize the arm code
≠TST≡≡R0≡≥	063724	005700				TST R0		;All well?
≠BEQ≡≥	063726	001404				BEQ 1$		;Yes
≤HALERR≡≥						HALERR STMES2	;No. complain.
≠MOV≡≡STMES2≡≡SP≡≥	063730	012746	064502			MOV #STMES2,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	063734	004777	730052			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠MOV≡≡SP≡≡R0≡≥	063740	012600			1$:	MOV (SP)+,R0	;R0 ← LOC[device block]
≠JSR≡≡PC≡≡RLFREE≡≥	063742	004767	744642			JSR PC,RLFREE	;Release it
≥					    .ENDC
≠JSR≡≡PC≡≡IOINIT≡≥	063746	004767	730446			JSR PC,IOINIT	;Initialize input-output
≥					
≥						;check to see that the PCODE is compatible
≠CMP≡≡PCDVER≡≡PCVERS≡≥	063752	026727	730024	000005		CMP PCDVER,#PCVERSION	;Version compatible?
≠BEQ≡≥	063760	001404				BEQ 2$		;Yes
≤HALERR≡≥						HALERR STMES	;No
≠MOV≡≡STMES≡≡SP≡≥	063762	012746	064330			MOV #STMES,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	063766	004777	730020			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≠CMP≡≡ARMVER≡≡VERSIO≡≥	063772	026727	730002	000010	2$:	CMP ARMVER,#VERSION	;Arm compatible?
≠BEQ≡≥	064000	001404				BEQ 3$		;Yes
≤HALERR≡≥						HALERR STMES1	;No
≠MOV≡≡STMES1≡≡SP≡≥	064002	012746	064416			MOV #STMES1,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	064006	004777	730000			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 294
	HAL PAL[HAL,HE]	PAGE 3.1 	Graph routines.

≥					
≥					3$:
≥						;set up the first interpreter
≠.IFNZ≡≡INTLOA≡≥		000001			    .IFNZ INTLOAD	;Initialize the interpreter
≠JSR≡≡PC≡≡INTINI≡≥	064012	004767	751276			JSR PC,INTINIT	;Initialize the interpreter events
≠MOV≡≡ENVIRO≡≡R0≡≥	064016	012700	063260			MOV #ENVIRO,R0	;Clear out the envrironment
≠MOV≡≡ENVLTH≡≡R1≡≥	064022	012701	000200			MOV #ENVLTH,R1	;
≠CLR≡≡R0≡≥	064026	005020			4$:	CLR (R0)+	;
≠SOB≡≡R1≡≥	064030	077102				SOB R1,4$	;
≠MOV≡≡ISBS≡≡R0≡≥	064032	012700	000017			MOV #ISBS,R0	;R0 ← Size (in words) of an interpreter status block
≠JSR≡≡PC≡≡GTFREE≡≥	064036	004767	744204			JSR PC,GTFREE	;R0 ← LOC[new interpreter status block]
≠CLR≡≡LEV≡≡R0≡≥	064042	005060	000010			CLR LEV(R0)	;new LEV ← 0
≠MOV≡≡R0≡≡NXTINT≡≡ISTBLK≡≥	064046	010067	777152			MOV R0,NXTINT+ISTBLK	;Prime the interpreter list.
≠CLR≡≡NXTINT≡≡R0≡≥	064052	005060	000002			CLR NXTINT(R0)	;
≠MOV≡≡PCODE≡≡IPC≡≡R0≡≥	064056	012760	130000	000000		MOV #PCODE,IPC(R0)	;new IPC ← interpreter start address
≠MOV≡≡ENVIRO≡≡ENV≡≡R0≡≥	064064	012760	063260	000006		MOV #ENVIRO,ENV(R0)	;new ENV ← ENVIRO
≤EVMAK≡≥						EVMAK		;-(SP) ← event for EVT in this interpreter
≥	064072	104004				104004
≠MOV≡≡SP≡≡EVT≡≡R0≡≥	064074	011660	000016			MOV (SP),EVT(R0);new EVT ← event just created.
≠MOV≡≡R0≡≡SP≡≥	064100	010046				MOV R0,-(SP)	;Save LOC[new interpreter status block]
≠MOV≡≡INSTSZ≡≡R0≡≥	064102	012700	000020			MOV #INSTSZ,R0	;R0 ← Size needed for an interpreter stack
≠JSR≡≡PC≡≡GTFREE≡≥	064106	004767	744134			JSR PC,GTFREE	;R0 ← LOC[new interpreter stack]
≠MOV≡≡SP≡≡R1≡≥	064112	012601				MOV (SP)+,R1	;R1 ← LOC[new interpreter status block]
≠MOV≡≡R0≡≡STKBAS≡≡R1≡≥	064114	010061	000004			MOV R0,STKBAS(R1)	;Store away new stack base
≠ADD≡≡INSTSZ≡≡R0≡≥	064120	062700	000040			ADD #2*INSTSZ,R0	;R0 ← LOC[top of new stack] (INSTSZ is in bytes)
≠MOV≡≡R1≡≡SP≡≥	064124	010146				MOV R1,-(SP)	;Save R1
≠MOV≡≡R0≡≡SP≡≥	064126	010046				MOV R0,-(SP)	;Save R0
≠MOV≡≡R0≡≥	064130	012700	000210			MOV #210,R0	;Room for process descriptor
≠JSR≡≡PC≡≡GTFREE≡≥	064134	004767	744106			JSR PC,GTFREE	;R0 ← LOC[new process descriptor]
≠MOV≡≡UFPUSE≡≡UGRSAV≡≡PDBSTA≡≡R0≡≥	064140	012760	104000	000000		MOV #UFPUSE+UGRSAV,PDBSTA(R0);Use floating point, use saved registers.
≠MOV≡≡UPDLEN≡≡R0≡≥	064146	012760	000420	000002		MOV #420,UPDLEN(R0)	;Length of PCB
≠MOV≡≡SP≡≡R1≡≥	064154	012601				MOV (SP)+,R1	;R1 ← LOC[new interpreter stack top]
≠MOV≡≡R1≡≡PDBR3≡≡R0≡≥	064156	010160	000034			MOV R1,PDBR3(R0)	;Store away new interp stack pointer (reg 3)
≠MOV≡≡SP≡≡R1≡≥	064162	012601				MOV (SP)+,R1		;R1 ← LOC[new ISB]
≠MOV≡≡R0≡≡PCB≡≡R1≡≥	064164	010061	000014			MOV R0,PCB(R1)		;Store away LOC[PCB] in new ISB
≠MOV≡≡R1≡≡PDBR4≡≡R0≡≥	064170	010160	000036			MOV R1,PDBR4(R0)	;Store away LOC[ISB] in reg 4 of PCB
≠.IFNZ≡≡ALAID≡≥		000001			    .IFNZ ALAID
≠MOV≡≡R1≡≡CURNAM≡≥	064174	010167	767240			MOV R1,CURNAM	;This is the current interpreter
≥					    .ENDC
≠MOV≡≡SP≡≡R1≡≥	064200	010601				MOV SP,R1	;
≠TST≡≡R1≡≥	064202	005721				TST (R1)+	;
≠MOV≡≡R1≡≡PDBSP≡≡R0≡≥	064204	010160	000014			MOV R1,PDBSP(R0)	;Store away the new stack pointer (reg 6)
≠MOV≡≡INTERP≡≡PDBPC≡≡R0≡≥	064210	012760	036016	000016		MOV #INTERP,PDBPC(R0);Store away the new PC
≠MOV≡≡UIMAP≡≡R0≡≥	064216	012760	000376	000022		MOV #376,UIMAP(R0)	;Map instruction space
≠MOV≡≡UDMAP≡≡R0≡≥	064224	012760	000576	000024	        MOV #576,UDMAP(R0)  ;Sets data space to map 1, which puts phys 160000
≠ADD≡≡PDBSTA≡≡R0≡≥	064232	062700	000000			ADD #PDBSTA,R0	;Move R0 to the middle of the process descriptor
≤SCHEDU≡≥						SCHEDU R0,#INTERP,#1,#2;Cause the new process to be started, suspended
≤.ARG≡≥						  .ARG #2
≠.LIF≡≥						    .LIF NB #2
≠MOV≡≡SP≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 295
	HAL PAL[HAL,HE]	PAGE 3.2 	Graph routines.

≥	064236	012746	000002			      MOV #2,-(SP)
≤.ARG≡≥						  .ARG #1
≠.LIF≡≥						    .LIF NB #1
≠MOV≡≡SP≡≥	064242	012746	000001			      MOV #1,-(SP)
≤.ARG≡≥						  .ARG #INTERP
≠.LIF≡≥						    .LIF NB #INTERP
≠MOV≡≡INTERP≡≡SP≡≥	064246	012746	036016			      MOV #INTERP,-(SP)
≤.ARG≡≥						  .ARG R0
≠.LIF≡≥						    .LIF NB R0
≠MOV≡≡R0≡≡SP≡≥	064252	010046				      MOV R0,-(SP)
≥	064254	104016				104016
≠.IFNZ≡≡ALAID≡≥		000001			    .IFNZ ALAID
≠JSR≡≡PC≡≡ALINIT≡≥	064256	004767	773540			JSR PC,ALINIT	;Initialize ALAID
≥					    .ENDC
≤EVWAIT≡≥						EVWAIT 		;Wait for the return signal
≤.ARG≡≥						  .ARG 
≠.LIF≡≥						    .LIF NB 
≥						      MOV ,-(SP)
≥	064262	104010				104010
≠BCC≡≥	064264	103004				BCC  5$		;All well?
≤HALERR≡≥						HALERR TSTMES	;No
≠MOV≡≡TSTMES≡≡SP≡≥	064266	012746	064554			MOV #TSTMES,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	064272	004777	727514			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤HALERR≡≥					5$:	HALERR TSTME1	;
≠MOV≡≡TSTME1≡≡SP≡≥	064276	012746	064616			MOV #TSTME1,-(SP)		;Push the message pointer.
≠JSR≡≡PC≡≡LERRTR≡≥	064302	004777	727504			JSR PC,@LERRTRAP	;No need to save registers.  This is done in ERRTRAP.
≤DISMIS≡≥						DISMIS		;Go away
≥	064306	104000				104000
≥					
≤ASCIE≡≥					PNTMES: ASCIE </CAN'T CONTINUE/>
≠.ASCIZ≡≥	064310	   103		
≥	064311	   101		
≥	064312	   116		
≥	064313	   047		
≥	064314	   124		
≥	064315	   040		
≥	064316	   103		
≥	064317	   117		
≥	064320	   116		
≥	064321	   124		
≥	064322	   111		
≥	064323	   116		
≥	064324	   125		
≥	064325	   105		
≥	064326	   000		
≥					       .ASCIZ /CAN'T CONTINUE/
≠.EVEN≡≥		064330			       .EVEN
≤ASCIE≡≥					STMES:	ASCIE </INCOMPATIBLE PCODE VERSION.  PROCEED AT YOUR OWN RISK/>
≠.ASCIZ≡≥	064330	   111		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 296
	HAL PAL[HAL,HE]	PAGE 3.3 	Graph routines.

≥	064331	   116		
≥	064332	   103		
≥	064333	   117		
≥	064334	   115		
≥	064335	   120		
≥	064336	   101		
≥	064337	   124		
≥	064340	   111		
≥	064341	   102		
≥	064342	   114		
≥	064343	   105		
≥	064344	   040		
≥	064345	   120		
≥	064346	   103		
≥	064347	   117		
≥	064350	   104		
≥	064351	   105		
≥	064352	   040		
≥	064353	   126		
≥	064354	   105		
≥	064355	   122		
≥	064356	   123		
≥	064357	   111		
≥	064360	   117		
≥	064361	   116		
≥	064362	   056		
≥	064363	   040		
≥	064364	   040		
≥	064365	   120		
≥	064366	   122		
≥	064367	   117		
≥	064370	   103		
≥	064371	   105		
≥	064372	   105		
≥	064373	   104		
≥	064374	   040		
≥	064375	   101		
≥	064376	   124		
≥	064377	   040		
≥	064400	   131		
≥	064401	   117		
≥	064402	   125		
≥	064403	   122		
≥	064404	   040		
≥	064405	   117		
≥	064406	   127		
≥	064407	   116		
≥	064410	   040		
≥	064411	   122		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 297
	HAL PAL[HAL,HE]	PAGE 3.4 	Graph routines.

≥	064412	   111		
≥	064413	   123		
≥	064414	   113		
≥	064415	   000		
≥					       .ASCIZ /INCOMPATIBLE PCODE VERSION.  PROCEED AT YOUR OWN RISK/
≠.EVEN≡≥		064416			       .EVEN
≤ASCIE≡≥					STMES1:	ASCIE </INCOMPATIBLE ARM VERSION.  PROCEED AT YOUR OWN RISK/>
≠.ASCIZ≡≥	064416	   111		
≥	064417	   116		
≥	064420	   103		
≥	064421	   117		
≥	064422	   115		
≥	064423	   120		
≥	064424	   101		
≥	064425	   124		
≥	064426	   111		
≥	064427	   102		
≥	064430	   114		
≥	064431	   105		
≥	064432	   040		
≥	064433	   101		
≥	064434	   122		
≥	064435	   115		
≥	064436	   040		
≥	064437	   126		
≥	064440	   105		
≥	064441	   122		
≥	064442	   123		
≥	064443	   111		
≥	064444	   117		
≥	064445	   116		
≥	064446	   056		
≥	064447	   040		
≥	064450	   040		
≥	064451	   120		
≥	064452	   122		
≥	064453	   117		
≥	064454	   103		
≥	064455	   105		
≥	064456	   105		
≥	064457	   104		
≥	064460	   040		
≥	064461	   101		
≥	064462	   124		
≥	064463	   040		
≥	064464	   131		
≥	064465	   117		
≥	064466	   125		
≥	064467	   122		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 298
	HAL PAL[HAL,HE]	PAGE 3.5 	Graph routines.

≥	064470	   040		
≥	064471	   117		
≥	064472	   127		
≥	064473	   116		
≥	064474	   040		
≥	064475	   122		
≥	064476	   111		
≥	064477	   123		
≥	064500	   113		
≥	064501	   000		
≥					       .ASCIZ /INCOMPATIBLE ARM VERSION.  PROCEED AT YOUR OWN RISK/
≠.EVEN≡≥		064502			       .EVEN
≤ASCIE≡≥					STMES2:	ASCIE </CAN'T INITIALIZE ARM.  ERROR CODE IN R0./>
≠.ASCIZ≡≥	064502	   103		
≥	064503	   101		
≥	064504	   116		
≥	064505	   047		
≥	064506	   124		
≥	064507	   040		
≥	064510	   111		
≥	064511	   116		
≥	064512	   111		
≥	064513	   124		
≥	064514	   111		
≥	064515	   101		
≥	064516	   114		
≥	064517	   111		
≥	064520	   132		
≥	064521	   105		
≥	064522	   040		
≥	064523	   101		
≥	064524	   122		
≥	064525	   115		
≥	064526	   056		
≥	064527	   040		
≥	064530	   040		
≥	064531	   105		
≥	064532	   122		
≥	064533	   122		
≥	064534	   117		
≥	064535	   122		
≥	064536	   040		
≥	064537	   103		
≥	064540	   117		
≥	064541	   104		
≥	064542	   105		
≥	064543	   040		
≥	064544	   111		
≥	064545	   116		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 299
	HAL PAL[HAL,HE]	PAGE 3.6 	Graph routines.

≥	064546	   040		
≥	064547	   122		
≥	064550	   060		
≥	064551	   056		
≥	064552	   000		
≥					       .ASCIZ /CAN'T INITIALIZE ARM.  ERROR CODE IN R0./
≠.EVEN≡≥		064554			       .EVEN
≤ASCIE≡≥					TSTMES: ASCIE </BAD RETURN FROM MAIN INTERPRETER/>
≠.ASCIZ≡≥	064554	   102		
≥	064555	   101		
≥	064556	   104		
≥	064557	   040		
≥	064560	   122		
≥	064561	   105		
≥	064562	   124		
≥	064563	   125		
≥	064564	   122		
≥	064565	   116		
≥	064566	   040		
≥	064567	   106		
≥	064570	   122		
≥	064571	   117		
≥	064572	   115		
≥	064573	   040		
≥	064574	   115		
≥	064575	   101		
≥	064576	   111		
≥	064577	   116		
≥	064600	   040		
≥	064601	   111		
≥	064602	   116		
≥	064603	   124		
≥	064604	   105		
≥	064605	   122		
≥	064606	   120		
≥	064607	   122		
≥	064610	   105		
≥	064611	   124		
≥	064612	   105		
≥	064613	   122		
≥	064614	   000		
≥					       .ASCIZ /BAD RETURN FROM MAIN INTERPRETER/
≠.EVEN≡≥		064616			       .EVEN
≤ASCIE≡≥				TSTME1: ASCIE </
≥				ALL DONE NOW.  SEE YOU AROUND!
≥					/>
≠.ASCIZ≡≥	064616	   015		
≥	064617	   012			       .ASCIZ /
≥	064620	   101		
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 300
	HAL PAL[HAL,HE]	PAGE 3.7 	Graph routines.

≥	064621	   114		
≥	064622	   114		
≥	064623	   040		
≥	064624	   104		
≥	064625	   117		
≥	064626	   116		
≥	064627	   105		
≥	064630	   040		
≥	064631	   116		
≥	064632	   117		
≥	064633	   127		
≥	064634	   056		
≥	064635	   040		
≥	064636	   040		
≥	064637	   123		
≥	064640	   105		
≥	064641	   105		
≥	064642	   040		
≥	064643	   131		
≥	064644	   117		
≥	064645	   125		
≥	064646	   040		
≥	064647	   101		
≥	064650	   122		
≥	064651	   117		
≥	064652	   125		
≥	064653	   116		
≥	064654	   104		
≥	064655	   041		
≥	064656	   015		
≥	064657	   012			ALL DONE NOW.  SEE YOU AROUND!
≥	064660	   000		
≥					/
≠.EVEN≡≥		064662			       .EVEN
≥					;End of the interpreter calling sequence
≥					
≥					.IFF		;do some test without the iterpreter
≥						.PRINT /Not loading the interpreter
≥					/
≥						JSR PC,TEST	;Try out whatever test routine has been loaded.
≥						DISMIS		;
≥					.ENDC
≥					
≠.BLKW≡≥		065062			PATCH:  .BLKW 100
≥					
≠.IFNZ≡≡INTLOA≡≡GRAPHS≡≥		000002			.IFNZ INTLOAD+GRAPHS
≤PUTLOC≡≥						PUTLOC LGETVAL, GETVAL
≡II≠≥		065062			        II==.
≡LGETVA≡≥		014004			        .= LGETVAL
≡GETVAL≡≡GETVAL≡	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 301
	HAL PAL[HAL,HE]	PAGE 3.8 	Graph routines.

≥	014004	060776			         GETVAL
≡II≡≥		065062			       .=II
≤PUTLOC≡≥						PUTLOC LGETARG, GETARG
≡II≠≥		065062			        II==.
≡LGETAR≡≥		014010			        .= LGETARG
≡GETARG≡≡GETARG≡≥	014010	036262			         GETARG
≡II≡≥		065062			       .=II
≤PUTLOC≡≥						PUTLOC LINVLDT, INVLDT
≡II≠≥		065062			        II==.
≡LINVLD≡≥		014006			        .= LINVLDT
≡INVLDT≡≡INVLDT≡≥	014006	060376			         INVLDT
≡II≡≥		065062			       .=II
≥					.ENDC
≥					
≠.IF2≡≥					.IF2
≡FOO≠≥		065062				FOO==.
≤.INFO≡≡FOO≡≥						.INFO <First location after interpreter = >,\FOO
≠.PRINT≡≥					                .PRINT /First location after interpreter = /
≠.PRINT≡≥				                .PRINT /65062
≥					/
≠.IFL≡≡ARMCOD≡≡FOO≡≥		000416				.IFL ARMCOD-FOO
≥						  .ERROR Interpreter runs into arm code.
≥						.ENDC
≥					.ENDC
≥					
≠.END≡≥		000001			.END 
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 302
	HAL PAL[HAL,HE]	PAGE 3 	***SYMBOL TABLE***      

	ABKSIZ	000007H		BUFSIZ	000200H		COMPAC	032460		ENDP	051126	
	ABORT	040202		C0001	042720		COMTAB	014000		ENDPCD	051164	
	AC0	000000RH		C1001	042714		CONSIN	014460		ENDSIZ	000011H	
	AC1	000001RH		CAR	000000H		COPY	037352		ENIPC	000016H	
	AC2	000002RH		CCNT	014630		CRLFX	014266		ENISB	000014H	
	AC3	000003RH		CDONE	051664		CSLEVT	014416		ENNEED	000020H	
	AC4	000004RH		CDR	000002H		CTHIRD	042710		ENV	000006H	
	AC5	000005RH		CELID	000004H		CURIN	015106		ENVID	000005H	
	ACH.CH	000002H		CELSPC	035016		CURNAM	053440		ENVIRO	063260	
	ACH.ND	000004H		CENTER	045046		CVE	052106		ENVLTH	000200H	
	ADCVEC	000134H		CHANGE	060500		CVF	052034		ENVSPC	035050	
	ADD.EN	000002H		CHG.ND	000004H		CVFX	050716		EPRT	052254	
	ADD.VN	000004H		CHG.VN	000002H		CVG	052342		ERRMES	055116	
	ADDBUF	034456		CHGCSZ	000003H		DACVEC	000130H		ERRTRA	014334	
	ADDCHG	060732		CHGIPC	000004H		DBS	014632		ERRTRP	000004H	
	ADDCLC	061572		CHGISB	000002H		DCLC	041324		ESIGN	052642	
	AGARG	000006H		CHKDG	051414		DDT	130000		EVALND	061074	
	AGBUF	000004H		CHKDN	051654		DEBMOD	000032H		EVE.EX	000004H	
	AGPTR	000010H		CHKDP	051462		DEBUG	000000H		EVE.T	000002H	
	AHAND	000012H		CHKEX	051522		DELEXP	062234		EVL.ND	000004H	
	ALAID	000001H		CHKSZ	052556		DELVN	062616		EVL.T	000002H	
	ALDEVT	053442		CHNGE	037124		DESEVT	050122		EVLEXP	061330	
	ALDSS	000001H		CHNGER	060640		DESFOR	047100		EVT	000016H	
	ALINIT	060022		CLKCNT	172544		DESMSG	047166		EXCN	051542	
	ALPDB	057302		CLKS	172540		DETECT	000000H		EXPON	052644	
	ANARM	000005H		CLKSET	172542		DGLST	052664		FERM	051770	
	AND	041676		CLKTRP	000104H		DIG	052654		FEXACT	030472	
	ANPTR	000002H		CMCB	000020H		DIG2	051576		FFOUND	030376	
	ANSBUF	000000H		CMCBSZ	000003H		DIGLP	052472		FFREE	000020H	
	ANSWER	000010H		CMDERR	046304		DLE.EN	000002H		FIXIT	051206	
	ARG1	000002H		CMDES	000002H		DODDT	057116		FIXM	051262	
	ARG2	000004H		CMDEST	046316		DODDTM	057234		FLOAT	000001H	
	ARMCOD	065500		CMDSBL	046252		DOERR	054452		FLUSH	037416	
	ARMTRP	000200H		CMENB	000001H		DOGETV	056032		FMBEX	000004H	
	ARMVER	014000		CMENBL	046212		DOGTBU	053746		FMFEX	000010H	
	ASDTE	000002H		CMMAK	045650		DONEME	055110		FMFOMO	000000H	
	BACOFS	000010H		CMMMSG	046070		DONOTI	057256		FMJOAN	000070H	
	BAOFST	000014H		CMNEMS	046146		DORLBU	054026		FMKIL	000002H	
	BARM	000004H		CMPOK	031720		DOSETN	056640		FMMECH	000120H	
	BARMSB	000770H		CMPSP	032206		DOSETV	056130		FMMODE	000126H	
	BDEPRO	000030H		CMSEVT	000000H		DOSIGN	056500		FMRETO	000040H	
	BHAND	000010H		CMSKED	046436		DOSTAR	056766		FMSCAL	000122H	
	BHANDS	000004H		CMSTAT	000004H		DOUSBU	054014		FMSIZ	000054H	
	BHCOFS	000012H		CMTEVT	000002H		DOWAIT	056560		FOO	065062H	
	BHOFST	000016H		CMTRIG	046372		DSLGTH	000004H		FORCHK	040232	
	BUFALC	000101H		CMUNCR	046570		DVBKSZ	000012H		FORMAT	051706	
	BUFHDR	000010H		COMP	041534		ENDCLC	041404		FREB.	034112	
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 303
	HAL PAL[HAL,HE]	PAGE 3 	***SYMBOL TABLE***      

	FREBER	034266		GLOBMS	037724		INTRP	014100H		LTHPTR	014026	
	FREBLK	034054		GLOBSR	037572		INVALI	036062		LUPDAT	014046	
	FREEND	030114		GNDEPS	000012H		INVLDT	060376		LVARS	000010H	
	FREEPT	015112		GNEND	000014H		INVLR0	060430		LWHERE	014020	
	FREEST	015116		GNEVT	060200		INVMRK	000006H		LWRIST	014034	
	FREL	005400		GNMODE	000000H		IOINIT	014420		MAINBL	031170	
	FRERMS	034156		GNODES	060172		IPC	000000H		MAKEVN	062466	
	FRESBK	034244		GNVAL	000010H		IREG	157774		MAKEVT	047776	
	FRINIT	030120		GODDT	040226		ISBS	000017H		MAKEXP	061710	
	FRINMS	030174		GOTCAR	014472		ISTBLK	063222		MAKFOR	046730	
	FRMS1	030510		GPHPTR	000014H		JOBDAT	013774H		MAKREQ	054644	
	FRMS2	030560		GRAPHS	000001H		JOBSA	013776H		MAKRT	047534	
	FROMEL	000002H		GSINIT	060202		JUMP	040274		MAP	000000H	
	FROMTE	000001H		GTFMES	047514		JUMPC	040304		MAPPTR	031756	
	FRRET	030436		GTFREE	030246		KBIR	177562		MAPRTN	000002H	
	FRTRY	030314		GTMS1	036354		KBIS	177560		MARK0	006400H	
	FSLGTH	000000H		GTNEW	041526		KBOR	177566		MARK1	006401H	
	FSTBLK	000006H		GTOLD	041520		KBOS	177564		MARK2	006402H	
	FSTBUF	000022H		GTV.ND	000002H		KERNEL	000001H		MARK3	006403H	
	GC	033176		GTVAL	036630		KTABLE	055140		MARK4	006404H	
	GCDONE	031716		GTVMS1	036732		KTEND	055210		MARK5	006405H	
	GCF	000006H		GTVMS2	037002		KVAR	036562		MARKPH	032056	
	GCFG	000010H		HCOR	157776		LACOS	014042		MARKQ	035266	
	GCOK	031714		IBUF	000150H		LBDEBU	000000H		MARKR0	032024	
	GERMSG	033700		ICHNGE	037270		LBEVT	015110		MAXGLB	000010H	
	GETARG	036262		IDF	000012H		LBMAP	031104		MAXIDF	000030H	
	GETBER	033664		IDFLAG	000000H		LCENTE	014016		MCELL	035224	
	GETBL	033460		IGTVAL	037060		LDVCPT	014030		MCHG	041414	
	GETBLK	033656		II	065062H		LERRPT	014024		MCLC	041244	
	GETBUF	000001H		ILGINS	000010H		LERRTR	014012		MERGR	030744	
	GETDG	052516		IN2	014436		LEV	000010H		MESBEG	000006H	
	GETFOR	047236		INBUF	014636		LFORCE	014044		MESID	000000H	
	GETNOT	053454		INSEND	000266		LGETAR	014010		MESLTH	000004H	
	GETOCT	055712		INSTR	014432		LGETVA	014004		MESTYP	000002H	
	GETOFS	054344		INSTSZ	000020H		LINKQU	054040		METH	000000H	
	GETSBK	033456		INT1	036026		LINTAR	014014		MEXP	041070	
	GETSCA	036424		INT2	036072		LINVLD	014006		MGNDS	063056	
	GETSID	033766		INTERP	036016		LMOVE	014022		MGNDSM	035214	
	GETTRN	036470		INTEVT	035310		LNKMTH	032042		MINTS	035344	
	GETVAL	060776		INTINI	035314		LOOKUP	055314		MINTSM	035220	
	GETVEC	036446		INTLOA	000001H		LOR	041744		MKE.IP	000004H	
	GETVR0	061010		INTMA1	000030H		LPAREN	055100		MKE.IS	000006H	
	GLBEND	037570		INTMS1	036106		LSETBA	014032		MKE.ND	000002H	
	GLBEVT	035312		INTMS2	036154		LSNCSD	014040		MKROUT	032176	
	GLBLIM	037562		INTMS3	036226		LSQRTF	014036		MKRTJM	032020	
	GLBLNK	037424		INTNAM	000026H		LSTBLK	000004H		MMETHS	031712	
	GLBTAB	037502		INTOPS	035530		LSTBUF	000024H		MOVE	045036	
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 304
	HAL PAL[HAL,HE]	PAGE 3 	***SYMBOL TABLE***      

	MOVERR	045320		OFYARM	000000H		PVDOT	042240		SBEVT	031710	
	MOVING	000001H		OFYHAN	000014H		QBUF	000006H		SBINIT	035102	
	MOVSTA	045056		OIPC	000006H		QEVT	000004H		SBLSIZ	000004H	
	MSIGN	052640		OLDD	052660		QID	000004H		SBRLST	042466	
	MUNLNK	032546		OLDV	000022H		QNEXT	000000H		SCACOD	000002H	
	MVAR	036512		OLDW	052656		QPREV	000002H		SCASPC	034700	
	MVDCOF	045644		OLEV	000002H		QUELTH	000004H		SCLID	000001H	
	MVMES1	045276		ONE	051332		R0	000000R		SDIV	042126	
	NALLOC	000026H		ONMONS	000001H		R1	000001R		SEQ	041646	
	NEWCEL	060316		OREG	157776		R2	000002R		SERVER	053610	
	NEWENV	035520		OUTBUF	014762		R3	000003R		SETBS	052612	
	NEWS.	034402		OUTSW	157772		R4	000004R		SETNAM	053420	
	NEWSPC	034322		PATCH	064662		R5	000005R		SETSPC	034450	
	NEWV	000024H		PAUSE	050166		RADIX	014146		SG	000005RH	
	NFER	051766		PC	000007R		RELBUF	000003H		SGE	041632	
	NFREE	000030H		PCB	000014H		RELSCN	051336		SGT	041616	
	NMIN	000012H		PCDBA	051112		REMCLC	062110		SIDCHN	035050H	
	NMN	000004H		PCDBH	051120		REPLAC	037374		SIDCNT	000000H	
	NNNN	006400H		PCDVER	014002		REQBUF	000000H		SIDHED	035050H	
	NOCMP	033356		PCODE	130000		REQEVT	000006H		SIDLST	031722	
	NOGC	033256		PCVERS	000005H		REQPTR	000002H		SIDTBL	031724	
	NOOP	050760		PDBPC	000016H		REQQUE	000010H		SIGNAL	050040	
	NORM	051630		PDBR0	000026H		REQRES	000004H		SIZE	000004H	
	NOT	042012		PDBR1	000030H		REQUES	000004H		SKIPOP	056020	
	NOTB10	157000		PDBR2	000032H		RETRY	045256		SKIPSP	056006	
	NOTB11	157020		PDBR3	000034H		RETURN	040146		SLE	041602	
	NOTICE	045540		PDBR4	000036H		RF	000005RH		SLINK	000000H	
	NOTSIZ	000003H		PDBR5	000040H		RLFREE	030610		SLT	041566	
	NPB	000010H		PDBSP	000014H		RLMS1	031002		SMALLB	000001H	
	NPC	000002H		PDBSTA	000000H		RLMS2	031052		SMBDBG	000000H	
	NPCT	000014H		PIC2	051574		RLOOKP	055374		SMUL	042110	
	NPERB	000006H		PICK	051364		RLRET	030766		SNAME	050730	
	NUM	052646		PLCCOD	000005H		RMC.EN	000002H		SNDANS	054532	
	NXTBUF	000000H		PLEV	000002H		RMC.VN	000004H		SNDNOT	053532	
	NXTCHG	000000H		PNTMES	064310		RNORM	051506		SNDREQ	054712	
	NXTEMT	104044H		POP	037332		ROUT	000002H		SNE	041662	
	NXTGN	000002H		PRINT	050210		RPAREN	055104		SNEG	042146	
	NXTID	053436		PROC	037746		RQBSIZ	000005H		SP	000006R	
	NXTINT	000002H		PROG	051000		RSTFOR	052016		SPACE	000002H	
	NXTMTH	000002H		PROGCD	051034		RTABLE	055212		SPAWN	040332	
	NXTSID	000016H		PRTF	052440		RTEND	055312		SPC	000002H	
	NXTTIM	060326		PRVBUF	000002H		RUG	130000		SPCADR	000002H	
	OBUF	000160H		PRVGN	000004H		RUGMES	014271		SPCC	000002H	
	OENV	000004H		PS	177776		RUNE	052424		SPCHDR	000032H	
	OFBARM	000016H		PT	052662		RUNF	052432		SPRMES	040734	
	OFBHAN	000032H		PTRSID	034032		SADD	042050		SPROUT	040562	
	OFSCOD	000001H		PUSH	037336		SAMEID	054110		SPSWIT	000000H	
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 305
	HAL PAL[HAL,HE]	PAGE 3 	***SYMBOL TABLE***      

	SQRT	042472		TRTMMS	054300		VADD	043620		XDESFO	000244H	
	SRVMES	053704		TSTME1	064616		VALIDF	000014H		XENDCL	000070H	
	SSBRMS	042442		TSTMES	064554		VALIDN	060176		XENDP	000250H	
	SSBRTN	042364		TTMUL	044226		VALPRN	050254		XFLUSH	000060H	
	SSUB	042066		TVADD	044150		VALPTR	000012H		XFORCH	000100H	
	STA	000012H		TVCOM	044110		VARPRN	050244		XGETFO	000240H	
	START	063660		TVMUL	043720		VCTCOD	000003H		XGLBLN	000016H	
	STKBAS	000004H		TVRET	044166		VCTID	000002H		XGTNEW	000036H	
	STMES	064330		TVSUB	044206		VCTSPC	034732		XGTOLD	000034H	
	STMES1	064416		TWO	042704		VDOT	042164		XGTVAL	000040H	
	STMES2	064502		TYPCHR	014170		VERSIO	000010H		XICHNG	000046H	
	STOP	045402		TYPDEC	014120		VIT	171000		XIGTVA	000042H	
	STRT11	000500		TYPDIG	014140		VITTS	170777		XINVAL	000012H	
	SVMUL	043504		TYPOCT	014130		VMAGN	042310		XJUMP	000062H	
	SWEEP	032562		TYPOUT	014162		VMAKE	043560		XJUMPC	000064H	
	SWEEP1	032610		TYPRET	014264		VNAME	050740		XKVAR	000014H	
	SWP.	032626		TYPSTR	014100		VNCHGS	000020H		XLOR	000132H	
	SZ	000014H		TYPVAL	050334		VNCLCS	000016H		XMAKEV	000020H	
	TABMES	046706		TYPVL	050374		VNDSIZ	000011H		XMAKFO	000242H	
	TABOFS	046612		TYPVRT	050364		VRET	043644		XMCHG	000032H	
	TACK	055776		UAC0	000050H		VSAXWR	044550		XMCLC	000026H	
	TACKV	050312		UCALL	000012H		VSUB	043672		XMEXP	000024H	
	TACKVA	050264		UDMAP	000024H		WAITE	050064		XMOVE	000002H	
	TAG	777777H		UDPUSE	040000H		WAITQ	053444		XMVAR	000012H	
	TAGID	777776H		UFEA	000044H		WAKEVT	000034H		XNOOP	000262H	
	TAKBUF	000102H		UFEC	000042H		WHERE	045464		XNOT	000134H	
	TAXAN	043174		UFPS	000046H		WIDTH	052652		XNOTIC	000010H	
	TAXIS	042724		UFPSAV	020000H		WORD0	000000H		XPAUSE	000106H	
	TEN	053170		UFPUSE	100000H		WTCH	052626		XPOP	000052H	
	TENLST	053164		UGR0	000026H		WTDP	052512		XPRINT	000252H	
	TENTH	053160		UGRSAV	004000H		WTSP	052622		XPROC	000072H	
	TERMIN	040766		UIMAP	000022H		XABORT	000110H		XPROG	000246H	
	THOUS	050204		UINTL	000010H		XAND	000130H		XPRT	052306	
	TIME	060174		UNITV	042476		XBRACE	000260H		XPUSH	000050H	
	TINVRT	044422		UNLINK	060230		XCENTE	000004H		XPVDOT	000156H	
	TMAGMS	043146		UNLQUE	054060		XCHNGE	000044H		XREPLA	000056H	
	TMAGN	042764		UPC	000016H		XCMDES	000230H		XRETUR	000074H	
	TMAKE	044030		UPCSAV	002000H		XCMDSB	000226H		XSADD	000140H	
	TNAME	050750		UPDLEN	000002H		XCMENB	000224H		XSDIV	000150H	
	TOLGE	052524		UPSW	000020H		XCMMAK	000222H		XSEQ	000124H	
	TOPAL	050762		USEBUF	000002H		XCMSKE	000234H		XSGE	000120H	
	TORIEN	042640		USKMAX	000006H		XCMTRI	000232H		XSGT	000122H	
	TPOS	042572		USKMIN	000004H		XCMUNC	000236H		XSIGNA	000102H	
	TRACOD	000004H		USKP	000014H		XCOPY	000054H		XSLE	000114H	
	TREATM	054132		USKSAV	010000H		XDCLC	000030H		XSLT	000116H	
	TRNID	000003H		USRORG	014000H		XDDT	000112H		XSMUL	000146H	
	TRNSPC	034764		UST0	000000H		XDESEV	000022H		XSNE	000126H	
	AL INTERPRETER	PALX 241	01/10/77  15:53:53	PAGE 306
	HAL PAL[HAL,HE]	PAGE 3 	***SYMBOL TABLE***      

	XSNEG	000144H	
	XSPROU	000076H	
	XSSBRT	000160H	
	XSSUB	000142H	
	XSTOP	000006H	
	XSVMUL	000170H	
	XTAXIS	000164H	
	XTERMI	000066H	
	XTINVR	000220H	
	XTMAGN	000162H	
	XTMAKE	000210H	
	XTOPAL	000264H	
	XTORIE	000204H	
	XTPOS	000202H	
	XTTMUL	000216H	
	XTVADD	000212H	
	XTVMUL	000200H	
	XTVSUB	000214H	
	XUNITV	000176H	
	XVADD	000172H	
	XVALPR	000254H	
	XVARPR	000256H	
	XVDOT	000154H	
	XVMAGN	000152H	
	XVMAKE	000166H	
	XVSAXW	000206H	
	XVSUB	000174H	
	XWAITE	000104H	
	XWHERE	000136H	
	YARM	000001H	
	YARMSB	176000H	
	YDEPRO	000032H	
	YELLOW	000000H	
	YESCMP	033400	
	YESGC	033300	
	YHAND	000002H	
	YHANDS	001000H	
	YTHMES	055125	
	.L.	000036H	
	.PDB	014050H	
	.W.	100000H	

1.5 WDS AVG INSN LENGTH

35 SECONDS RUN-TIME